Directory: | ./ |
---|---|
File: | src/Graph_impl.h |
Date: | 2025-03-14 11:38:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 218 | 225 | 96.9% |
Branches: | 186 | 228 | 81.6% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /*************************************** | ||
2 | Auteur : Pierre Aubert | ||
3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
4 | Licence : CeCILL-C | ||
5 | ****************************************/ | ||
6 | |||
7 | #ifndef __GRAPH_H_IMPL__ | ||
8 | #define __GRAPH_H_IMPL__ | ||
9 | |||
10 | #include <stdlib.h> | ||
11 | #include <iostream> | ||
12 | |||
13 | #include "Graph.h" | ||
14 | |||
15 | ///Default constructeur of Graph | ||
16 | template<typename T, typename UIdx> | ||
17 | 5 | Graph<T, UIdx>::Graph(){ | |
18 | 5 | initialisationGraph(); | |
19 | 5 | } | |
20 | |||
21 | ///Copy constructor of Graph | ||
22 | /** @param other : class to copy | ||
23 | */ | ||
24 | template<typename T, typename UIdx> | ||
25 | 1 | Graph<T, UIdx>::Graph(const Graph<T, UIdx> & other){ | |
26 |
1/1✓ Branch 1 taken 1 times.
|
1 | copyGraph(other); |
27 | 1 | } | |
28 | |||
29 | ///Destructeur of Graph | ||
30 | template<typename T, typename UIdx> | ||
31 | 12 | Graph<T, UIdx>::~Graph(){ | |
32 | |||
33 | } | ||
34 | |||
35 | ///Definition of equal operator of Graph | ||
36 | /** @param other : class to copy | ||
37 | * @return copied class | ||
38 | */ | ||
39 | template<typename T, typename UIdx> | ||
40 | Graph<T, UIdx> & Graph<T, UIdx>::operator = (const Graph<T, UIdx> & other){ | ||
41 | copyGraph(other); | ||
42 | return *this; | ||
43 | } | ||
44 | |||
45 | ///Save a png file of the graph | ||
46 | /** @param fileNamePng : name of the png file | ||
47 | * @return true on success, false otherwise | ||
48 | */ | ||
49 | template<typename T, typename UIdx> | ||
50 | 9 | bool Graph<T, UIdx>::savePng(const std::string & fileNamePng) const{ | |
51 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
|
9 | if(fileNamePng == "") return false; |
52 |
1/1✓ Branch 2 taken 8 times.
|
8 | std::string fileTxt("output.dot"); |
53 |
2/3✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
|
8 | if(!saveDot(fileTxt)){ |
54 | ✗ | std::cerr << "Graph<T, UIdx>::savePng : can't create file '" << fileTxt << "'" << std::endl; | |
55 | ✗ | return false; | |
56 | } | ||
57 |
5/5✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
✓ Branch 10 taken 8 times.
✓ Branch 13 taken 8 times.
|
16 | std::string commande("dot -Tpng -o " + fileNamePng + " " + fileTxt + " && rm " + fileTxt); |
58 |
3/3✓ Branch 2 taken 8 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
|
8 | if(system(commande.c_str()) != 0){ |
59 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
1 | std::cerr << "Graph<T, UIdx>::savePng : can't create png file '" << fileNamePng << "'" << std::endl; |
60 | 1 | return false; | |
61 | } | ||
62 | 7 | return true; | |
63 | 8 | } | |
64 | |||
65 | ///Save the Graph in a dot file | ||
66 | /** @param fileName : name of the file to be created | ||
67 | */ | ||
68 | template<typename T, typename UIdx> | ||
69 | 10 | bool Graph<T, UIdx>::saveDot(const std::string & fileName) const{ | |
70 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
|
10 | if(fileName == ""){return false;} |
71 |
1/1✓ Branch 1 taken 9 times.
|
9 | std::ofstream fs; |
72 |
1/1✓ Branch 2 taken 9 times.
|
9 | fs.open(fileName.c_str()); |
73 |
3/3✓ Branch 1 taken 9 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 8 times.
|
9 | if(!fs.is_open()){ |
74 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
1 | std::cerr << "Graph<T, UIdx>::saveDot : can't open file '" << fileName << "'" << std::endl; |
75 | 1 | return false; | |
76 | } | ||
77 |
1/1✓ Branch 1 taken 8 times.
|
8 | bool b(saveDot(fs)); |
78 |
1/1✓ Branch 1 taken 8 times.
|
8 | fs.close(); |
79 | 8 | return b; | |
80 | 9 | } | |
81 | |||
82 | ///Save the Graph in a dot file | ||
83 | /** @param[out] fs : file stream to be modified | ||
84 | */ | ||
85 | template<typename T, typename UIdx> | ||
86 | 8 | bool Graph<T, UIdx>::saveDot(std::ofstream & fs) const{ | |
87 |
1/1✓ Branch 2 taken 8 times.
|
8 | fs << toDot(); |
88 | 8 | return true; | |
89 | } | ||
90 | |||
91 | ///Convert the graph to dot language | ||
92 | /** @return dot | ||
93 | */ | ||
94 | template<typename T, typename UIdx> | ||
95 | 8 | std::string Graph<T, UIdx>::toDot() const{ | |
96 |
1/1✓ Branch 2 taken 8 times.
|
8 | std::string body(""); |
97 |
1/1✓ Branch 1 taken 8 times.
|
8 | body += "digraph G{\n"; |
98 | //save the node definition | ||
99 |
2/2✓ Branch 3 taken 41 times.
✓ Branch 4 taken 8 times.
|
49 | for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator it(p_mapNode.begin()); it != p_mapNode.end(); ++it){ |
100 |
2/2✓ Branch 2 taken 41 times.
✓ Branch 5 taken 41 times.
|
41 | body += it->second.getDotDefinition(); |
101 | } | ||
102 | //save the connections between nodes | ||
103 |
2/2✓ Branch 5 taken 41 times.
✓ Branch 6 taken 8 times.
|
49 | for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){ |
104 |
1/1✓ Branch 2 taken 41 times.
|
41 | const std::string & parentNodeName(itNode->second.getDotName()); |
105 | 41 | const std::list<UIdx> & listChild = itNode->second.getListChild(); | |
106 |
2/2✓ Branch 4 taken 37 times.
✓ Branch 5 taken 41 times.
|
78 | for(typename std::list<UIdx>::const_iterator it(listChild.begin()); it != listChild.end(); ++it){ |
107 |
2/2✓ Branch 2 taken 37 times.
✓ Branch 5 taken 4 times.
|
37 | const Node<T, UIdx> * childNode = getNode(*it); |
108 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
|
37 | if(childNode == NULL){continue;} |
109 |
1/1✓ Branch 1 taken 37 times.
|
37 | const std::string & childNodeName(childNode->getDotName()); |
110 |
5/5✓ Branch 1 taken 37 times.
✓ Branch 4 taken 37 times.
✓ Branch 7 taken 37 times.
✓ Branch 10 taken 37 times.
✓ Branch 13 taken 37 times.
|
37 | body += "\t" + parentNodeName + " -> " + childNodeName + "[color=\"red\"];\n"; |
111 | } | ||
112 | } | ||
113 |
1/1✓ Branch 1 taken 8 times.
|
8 | body += "}\n\n"; |
114 | 8 | return body; | |
115 | } | ||
116 | |||
117 | ///Create a node and get its index | ||
118 | /** @param data : data of the Node | ||
119 | * @param name : name of the Node | ||
120 | * @return index of the Node | ||
121 | */ | ||
122 | template<typename T, typename UIdx> | ||
123 | 21 | UIdx Graph<T, UIdx>::createNode(const T & data, const std::string & name){ | |
124 | 21 | UIdx nodeIndex(p_mapNode.size()); | |
125 |
2/3✓ Branch 1 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
|
21 | while(getNode(nodeIndex) != NULL){ |
126 | ✗ | ++nodeIndex; | |
127 | } | ||
128 |
1/1✓ Branch 1 taken 21 times.
|
21 | Node<T, UIdx> node(data, name); |
129 | 21 | node.setIndex(nodeIndex); | |
130 |
2/2✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
|
21 | p_mapNode[nodeIndex] = node; |
131 | 21 | return nodeIndex; | |
132 | 21 | } | |
133 | |||
134 | ///Create a node and get its pointer | ||
135 | /** @param data : data of the Node | ||
136 | * @param name : name of the Node | ||
137 | * @return pointer of the Node | ||
138 | */ | ||
139 | template<typename T, typename UIdx> | ||
140 | Node<T, UIdx> * Graph<T, UIdx>::createNodePtr(const T & data, const std::string & name){ | ||
141 | UIdx node = createNode(data, name); | ||
142 | return getNode(node); | ||
143 | } | ||
144 | |||
145 | ///Create a node and get its index | ||
146 | /** @param data : data of the Node | ||
147 | * @param index : index of the Node | ||
148 | * @param name : name of the Node | ||
149 | * @return true if the node can be created, false if the index is already taken by an other Node | ||
150 | */ | ||
151 | template<typename T, typename UIdx> | ||
152 | 5 | bool Graph<T, UIdx>::createNode(const T & data, const UIdx & index, const std::string & name){ | |
153 |
3/4✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
|
5 | if(getNode(index) != NULL){ //Check if the Node already exists |
154 | ✗ | return false; | |
155 | } | ||
156 |
1/1✓ Branch 1 taken 5 times.
|
5 | Node<T, UIdx> node(data, name); |
157 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
|
5 | node.setIndex(index); |
158 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
|
5 | p_mapNode[index] = node; |
159 | 5 | return true; | |
160 | 5 | } | |
161 | |||
162 | ///Create a node and get its pointer | ||
163 | /** @param data : data of the Node | ||
164 | * @param index : index of the Node | ||
165 | * @param name : name of the Node | ||
166 | * @return pointer of the Node | ||
167 | */ | ||
168 | template<typename T, typename UIdx> | ||
169 | Node<T, UIdx> * Graph<T, UIdx>::createNodePtr(const T & data, const UIdx & index, const std::string & name){ | ||
170 | if(createNode(data, index, name)){ | ||
171 | return getNode(index); | ||
172 | }else{ | ||
173 | return NULL; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | ///Clear the isUpdated attriburte of the Node | ||
178 | template<typename T, typename UIdx> | ||
179 | 2 | void Graph<T, UIdx>::clearIsUpdated(){ | |
180 |
2/2✓ Branch 4 taken 10 times.
✓ Branch 5 taken 2 times.
|
12 | for(typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.begin()); it != p_mapNode.end(); ++it){ |
181 | 10 | it->second.setIsUpdated(false); | |
182 | } | ||
183 | 2 | } | |
184 | |||
185 | ///Clear the map of Node | ||
186 | template<typename T, typename UIdx> | ||
187 | void Graph<T, UIdx>::clearMapNode(){p_mapNode.clear();} | ||
188 | |||
189 | ///Clear the list of first Node | ||
190 | template<typename T, typename UIdx> | ||
191 | 1 | void Graph<T, UIdx>::clearFirstNode(){p_listFirstNode.clear();} | |
192 | |||
193 | ///Clear the list of last Node | ||
194 | template<typename T, typename UIdx> | ||
195 | 1 | void Graph<T, UIdx>::clearLastNode(){p_listLastNode.clear();} | |
196 | |||
197 | //Clear all Node | ||
198 | template<typename T, typename UIdx> | ||
199 | void Graph<T, UIdx>::clearAll(){ | ||
200 | clearFirstNode(); | ||
201 | clearLastNode(); | ||
202 | clearMapNode(); | ||
203 | } | ||
204 | |||
205 | ///Remove a Node from the Graph | ||
206 | /** @param index : index of the Node to be removed | ||
207 | * @param reconnectParentToChildren : true to reconnect parents of the node to be removed to its children | ||
208 | */ | ||
209 | template<typename T, typename UIdx> | ||
210 | 2 | void Graph<T, UIdx>::removeNode(UIdx index, bool reconnectParentToChildren){ | |
211 | 2 | Node<T, UIdx> * indexNode = getNode(index); | |
212 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(indexNode == NULL){return;} //If the Node does not exist, we stop |
213 | //Get the parents of the current Node | ||
214 | 2 | std::list<UIdx> & listParent = indexNode->getListParent(); | |
215 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if(listParent.size() != 0lu){ |
216 | //Tell them they do not have child anymore | ||
217 |
2/2✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){ |
218 |
1/1✓ Branch 2 taken 2 times.
|
2 | Node<T, UIdx> * parentNode = getNode(*it); |
219 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(parentNode == NULL){continue;} |
220 |
1/1✓ Branch 1 taken 2 times.
|
2 | parentNode->removeChild(index); |
221 | } | ||
222 | }else{ | ||
223 | //Let's remove the current Node from first Node | ||
224 | ✗ | listindex_remove(p_listFirstNode, index); | |
225 | } | ||
226 | //Get the children of the current Node | ||
227 | 2 | std::list<UIdx> & listChild = indexNode->getListChild(); | |
228 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if(listChild.size() != 0lu){ |
229 | //Tell them they do not have parent anymore | ||
230 |
2/2✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | for(typename std::list<UIdx>::iterator it(listChild.begin()); it != listChild.end(); ++it){ |
231 |
1/1✓ Branch 2 taken 2 times.
|
2 | Node<T, UIdx> * childNode = getNode(*it); |
232 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(childNode == NULL){continue;} |
233 | 2 | childNode->removeParent(index); | |
234 | } | ||
235 | }else{ | ||
236 | //Let's remove the current Node from last Node | ||
237 | ✗ | listindex_remove(p_listLastNode, index); | |
238 | } | ||
239 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
|
2 | if(reconnectParentToChildren && listParent.size() != 0lu && listChild.size() != 0lu){ |
240 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){ |
241 |
1/1✓ Branch 2 taken 1 times.
|
1 | connectNode(*it, listChild); |
242 | } | ||
243 | } | ||
244 | //Now, let's remove the current Node | ||
245 | 2 | p_mapNode.erase(index); | |
246 | } | ||
247 | |||
248 | ///Update the first and last Node of the Graph | ||
249 | template<typename T, typename UIdx> | ||
250 | 1 | void Graph<T, UIdx>::updateFirstLastNode(){ | |
251 | 1 | clearFirstNode(); | |
252 | 1 | clearLastNode(); | |
253 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
|
6 | for(typename std::map<UIdx, Node<T, UIdx> >::iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){ |
254 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
|
5 | if(itNode->second.isStart()){ //If the Node does not have any parent, it is a first Node |
255 |
1/1✓ Branch 2 taken 3 times.
|
3 | p_listFirstNode.push_back(itNode->first); |
256 | } | ||
257 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
|
5 | if(itNode->second.isEnd()){ //If the Node does not have any child, it is a last Node |
258 |
1/1✓ Branch 2 taken 1 times.
|
1 | p_listLastNode.push_back(itNode->first); |
259 | } | ||
260 | } | ||
261 | 1 | } | |
262 | |||
263 | ///Connect a parent to its child | ||
264 | /** @param parent : index of the parent Node | ||
265 | * @param child : index of the child Node | ||
266 | */ | ||
267 | template<typename T, typename UIdx> | ||
268 | 24 | void Graph<T, UIdx>::connectNode(UIdx parent, UIdx child){ | |
269 |
1/1✓ Branch 2 taken 4 times.
|
24 | Node<T, UIdx> * parentNode = getNode(parent); |
270 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if(parentNode == NULL){return;} |
271 |
1/1✓ Branch 2 taken 4 times.
|
24 | Node<T, UIdx> * childNode = getNode(child); |
272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if(childNode == NULL){return;} |
273 |
1/1✓ Branch 2 taken 4 times.
|
24 | parentNode->addChild(child); |
274 |
1/1✓ Branch 2 taken 4 times.
|
24 | childNode->addParent(parent); |
275 | } | ||
276 | |||
277 | ///Connect a parent to its children | ||
278 | /** @param parent : index of the parent Node | ||
279 | * @param listChildren : list of the children index | ||
280 | */ | ||
281 | template<typename T, typename UIdx> | ||
282 | 1 | void Graph<T, UIdx>::connectNode(UIdx parent, const std::list<UIdx> & listChildren){ | |
283 | 1 | Node<T, UIdx> * parentNode = getNode(parent); | |
284 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if(parentNode == NULL){return;} |
285 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | for(typename std::list<UIdx>::const_iterator it(listChildren.begin()); it != listChildren.end(); ++it){ |
286 | 1 | UIdx child = *it; | |
287 |
1/1✓ Branch 1 taken 1 times.
|
1 | Node<T, UIdx> * childNode = getNode(child); |
288 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if(childNode == NULL){continue;} |
289 |
1/1✓ Branch 1 taken 1 times.
|
1 | parentNode->addChild(child); |
290 |
1/1✓ Branch 1 taken 1 times.
|
1 | childNode->addParent(parent); |
291 | } | ||
292 | } | ||
293 | |||
294 | ///Connect a parent to its children | ||
295 | /** @param parent : index of the parent Node | ||
296 | * @param vecChildren : vector of the children index | ||
297 | */ | ||
298 | template<typename T, typename UIdx> | ||
299 | void Graph<T, UIdx>::connectNode(UIdx parent, const std::vector<UIdx> & vecChildren){ | ||
300 | Node<T, UIdx> * parentNode = getNode(parent); | ||
301 | if(parentNode == NULL){return;} | ||
302 | for(typename std::vector<UIdx>::const_iterator it(vecChildren.begin()); it != vecChildren.end(); ++it){ | ||
303 | UIdx child = *it; | ||
304 | Node<T, UIdx> * childNode = getNode(child); | ||
305 | if(childNode == NULL){continue;} | ||
306 | parentNode->addChild(child); | ||
307 | childNode->addParent(parent); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | ///Get a Node by pointer | ||
312 | /** @param index : index of the node to be used | ||
313 | * @return pointer to this Node or NULL if the Node does not exist | ||
314 | */ | ||
315 | template<typename T, typename UIdx> | ||
316 | 58 | const Node<T, UIdx> * Graph<T, UIdx>::getNode(UIdx index) const{ | |
317 |
1/1✓ Branch 1 taken 58 times.
|
58 | typename std::map<UIdx, Node<T, UIdx> >::const_iterator it(p_mapNode.find(index)); |
318 |
1/2✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
|
58 | if(it != p_mapNode.end()){ |
319 | 58 | return &(it->second); | |
320 | }else{ | ||
321 | ✗ | return NULL; | |
322 | } | ||
323 | } | ||
324 | |||
325 | ///Get a Node by pointer | ||
326 | /** @param index : index of the node to be used | ||
327 | * @return pointer to this Node or NULL if the Node does not exist | ||
328 | */ | ||
329 | template<typename T, typename UIdx> | ||
330 | 100 | Node<T, UIdx> * Graph<T, UIdx>::getNode(UIdx index){ | |
331 |
1/1✓ Branch 1 taken 100 times.
|
100 | typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.find(index)); |
332 |
2/2✓ Branch 2 taken 74 times.
✓ Branch 3 taken 26 times.
|
100 | if(it != p_mapNode.end()){ |
333 | 74 | return &(it->second); | |
334 | }else{ | ||
335 | 26 | return NULL; | |
336 | } | ||
337 | } | ||
338 | |||
339 | ///Get the first node which is not udpated (getIsUpdated() == false) | ||
340 | /** @return pointer to the first node which is not udpated or NULL if there is no | ||
341 | */ | ||
342 | template<typename T, typename UIdx> | ||
343 | const Node<T, UIdx> * Graph<T, UIdx>::getFirstNotUpdatedNode() const{ | ||
344 | for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){ | ||
345 | if(!itNode->second.getIsUpdated()){ | ||
346 | return &(itNode->second); | ||
347 | } | ||
348 | } | ||
349 | return NULL; | ||
350 | } | ||
351 | |||
352 | ///Get the first node which is not udpated (getIsUpdated() == false) | ||
353 | /** @return pointer to the first node which is not udpated or NULL if there is no | ||
354 | */ | ||
355 | template<typename T, typename UIdx> | ||
356 | Node<T, UIdx> * Graph<T, UIdx>::getFirstNotUpdatedNode(){ | ||
357 | for(typename std::map<UIdx, Node<T, UIdx> >::iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){ | ||
358 | if(!itNode->second.getIsUpdated()){ | ||
359 | return &(itNode->second); | ||
360 | } | ||
361 | } | ||
362 | return NULL; | ||
363 | } | ||
364 | |||
365 | ///Say if the node at index does exit | ||
366 | /** @param index : index of the node to be searched | ||
367 | * @return true if the Node does exist, false otheriwse | ||
368 | */ | ||
369 | template<typename T, typename UIdx> | ||
370 | bool Graph<T, UIdx>::isNodeExist(UIdx index) const{ | ||
371 | typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.find(index)); | ||
372 | return it != p_mapNode.end(); | ||
373 | } | ||
374 | |||
375 | ///Get the number of nodes inside the graph | ||
376 | /** @return number of nodes inside the graph | ||
377 | */ | ||
378 | template<typename T, typename UIdx> | ||
379 | 1 | size_t Graph<T, UIdx>::size() const{ | |
380 | 1 | return p_mapNode.size(); | |
381 | } | ||
382 | |||
383 | ///Get the list of the first nodes (without parent) | ||
384 | /** @return list of the first nodes (without parent) | ||
385 | */ | ||
386 | template<typename T, typename UIdx> | ||
387 | 2 | const std::list<UIdx> & Graph<T, UIdx>::getListFirstNode() const{ | |
388 | 2 | return p_listFirstNode; | |
389 | } | ||
390 | |||
391 | ///Get the list of the last nodes (without child) | ||
392 | /** @return list of the last nodes (without child) | ||
393 | */ | ||
394 | template<typename T, typename UIdx> | ||
395 | 2 | const std::list<UIdx> & Graph<T, UIdx>::getListLastNode() const{ | |
396 | 2 | return p_listLastNode; | |
397 | } | ||
398 | |||
399 | ///Iterate from parents to chidren | ||
400 | /** @param[out] listNode : list node which can be treated simultaneously | ||
401 | * @return true if the returned list of nodes is not empty, false if the bottom of the Graph has been reached | ||
402 | */ | ||
403 | template<typename T, typename UIdx> | ||
404 | 4 | bool Graph<T, UIdx>::iterateChildren(std::list<UIdx> & listNode) const{ | |
405 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if(listNode.size() == 0lu){ |
406 | 1 | listNode = getListFirstNode(); | |
407 | }else{ | ||
408 | 3 | std::map<UIdx, bool> mapListChildren; | |
409 |
2/2✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
|
9 | for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){ |
410 |
1/1✓ Branch 2 taken 6 times.
|
6 | const Node<T, UIdx> * node = getNode(*itNode); |
411 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if(node != NULL){ |
412 | 6 | const std::list<UIdx> & listChildren = node->getListChild(); | |
413 |
2/2✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6 times.
|
10 | for(typename std::list<UIdx>::const_iterator it(listChildren.begin()); it != listChildren.end(); ++it){ |
414 |
1/1✓ Branch 2 taken 4 times.
|
4 | mapListChildren[*it] = true; |
415 | } | ||
416 | } | ||
417 | } | ||
418 | 3 | std::list<UIdx> listNodeOut; | |
419 |
2/2✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
|
6 | for(typename std::map<UIdx, bool>::iterator it(mapListChildren.begin()); it != mapListChildren.end(); ++it){ |
420 |
1/1✓ Branch 2 taken 3 times.
|
3 | listNodeOut.push_back(it->first); |
421 | } | ||
422 |
1/1✓ Branch 1 taken 3 times.
|
3 | listNode = listNodeOut; |
423 | 3 | } | |
424 | 4 | return listNode.size() != 0lu; | |
425 | } | ||
426 | |||
427 | ///Iterate from children to parents | ||
428 | /** @param[out] listNode : list node which can be treated simultaneously | ||
429 | * @return true if the returned list of nodes is not empty, false if the top of the Graph has been reached | ||
430 | */ | ||
431 | template<typename T, typename UIdx> | ||
432 | 4 | bool Graph<T, UIdx>::iterateParent(std::list<UIdx> & listNode) const{ | |
433 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if(listNode.size() == 0lu){ |
434 | 1 | listNode = getListLastNode(); | |
435 | }else{ | ||
436 | 3 | std::map<UIdx, bool> mapListParent; | |
437 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
|
8 | for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){ |
438 |
1/1✓ Branch 2 taken 5 times.
|
5 | const Node<T, UIdx> * node = getNode(*itNode); |
439 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if(node != NULL){ |
440 | 5 | const std::list<UIdx> & listParent = node->getListParent(); | |
441 |
2/2✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5 times.
|
9 | for(typename std::list<UIdx>::const_iterator it(listParent.begin()); it != listParent.end(); ++it){ |
442 |
1/1✓ Branch 2 taken 4 times.
|
4 | mapListParent[*it] = true; |
443 | } | ||
444 | } | ||
445 | } | ||
446 | 3 | std::list<UIdx> listNodeOut; | |
447 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 3 times.
|
7 | for(typename std::map<UIdx, bool>::iterator it(mapListParent.begin()); it != mapListParent.end(); ++it){ |
448 |
1/1✓ Branch 2 taken 4 times.
|
4 | listNodeOut.push_back(it->first); |
449 | } | ||
450 |
1/1✓ Branch 1 taken 3 times.
|
3 | listNode = listNodeOut; |
451 | 3 | } | |
452 | 4 | return listNode.size() != 0lu; | |
453 | } | ||
454 | |||
455 | ///Check if the list of given nodes are all updated or not | ||
456 | /** @param listNode : list of nodes to be checked | ||
457 | * @return true fi all nodes are updated, false otherwise | ||
458 | */ | ||
459 | template<typename T, typename UIdx> | ||
460 | 7 | bool Graph<T, UIdx>::isListNodeUdpated(const std::list<UIdx> & listNode) const{ | |
461 | 7 | bool b(true); | |
462 |
5/6✓ Branch 4 taken 10 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 7 times.
|
17 | for(typename std::list<UIdx>::const_iterator itNode(listNode.begin()); itNode != listNode.end() && b; ++itNode){ |
463 |
1/1✓ Branch 2 taken 10 times.
|
10 | const Node<T, UIdx> * node = getNode(*itNode); |
464 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | if(node != NULL){ |
465 | 10 | b &= node->getIsUpdated(); | |
466 | } | ||
467 | } | ||
468 | 7 | return b; | |
469 | } | ||
470 | |||
471 | ///Iterate from parents to chidren (all node are iterated only once) | ||
472 | /** @param[out] listNode : list node which can be treated simultaneously | ||
473 | * @return true if the returned list of nodes is not empty, false if the bottom of the Graph has been reached | ||
474 | */ | ||
475 | template<typename T, typename UIdx> | ||
476 | 3 | bool Graph<T, UIdx>::iterateChildrenCheckUpdate(std::list<UIdx> & listNode){ | |
477 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
|
3 | if(listNode.size() == 0lu){ |
478 | 1 | clearIsUpdated(); | |
479 | 1 | listNode = getListFirstNode(); | |
480 | }else{ | ||
481 | 2 | std::map<UIdx, bool> mapListChildren; | |
482 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 5 taken 2 times.
|
7 | for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){ |
483 |
1/1✓ Branch 2 taken 5 times.
|
5 | Node<T, UIdx> * node = getNode(*itNode); |
484 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if(node != NULL){ |
485 | 5 | node->setIsUpdated(true); //This node has been iterated, so we do not want to pick it as a child | |
486 | 5 | std::list<UIdx> & listChildren = node->getListChild(); | |
487 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 5 times.
|
9 | for(typename std::list<UIdx>::iterator it(listChildren.begin()); it != listChildren.end(); ++it){ |
488 |
1/1✓ Branch 2 taken 4 times.
|
4 | Node<T, UIdx> * nodeChild = getNode(*it); |
489 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if(nodeChild != NULL){ |
490 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | if(!nodeChild->getIsUpdated()){ |
491 | //The child node is added only if its parents are updated | ||
492 |
3/3✓ Branch 2 taken 3 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
|
3 | if(isListNodeUdpated(nodeChild->getListParent())){ |
493 |
1/1✓ Branch 2 taken 2 times.
|
2 | mapListChildren[*it] = true; |
494 | 2 | nodeChild->setIsUpdated(true); | |
495 | } | ||
496 | } | ||
497 | } | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | 2 | std::list<UIdx> listNodeOut; | |
502 |
2/2✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | for(typename std::map<UIdx, bool>::iterator it(mapListChildren.begin()); it != mapListChildren.end(); ++it){ |
503 |
1/1✓ Branch 2 taken 2 times.
|
2 | listNodeOut.push_back(it->first); |
504 | } | ||
505 |
1/1✓ Branch 1 taken 2 times.
|
2 | listNode = listNodeOut; |
506 | 2 | } | |
507 | 3 | return listNode.size() != 0lu; | |
508 | } | ||
509 | |||
510 | ///Iterate from children to parents (all node are iterated only once) | ||
511 | /** @param[out] listNode : list node which can be treated simultaneously | ||
512 | * @return true if the returned list of nodes is not empty, false if the top of the Graph has been reached | ||
513 | */ | ||
514 | template<typename T, typename UIdx> | ||
515 | 4 | bool Graph<T, UIdx>::iterateParentCheckUpdate(std::list<UIdx> & listNode){ | |
516 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if(listNode.size() == 0lu){ |
517 | 1 | clearIsUpdated(); | |
518 | 1 | listNode = getListLastNode(); | |
519 | }else{ | ||
520 | 3 | std::map<UIdx, bool> mapListParent; | |
521 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
|
8 | for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){ |
522 |
1/1✓ Branch 2 taken 5 times.
|
5 | Node<T, UIdx> * node = getNode(*itNode); |
523 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if(node != NULL){ |
524 | 5 | node->setIsUpdated(true); //This node has been iterated, so we do not want to pick it as a parent | |
525 | 5 | std::list<UIdx> & listParent = node->getListParent(); | |
526 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 5 times.
|
9 | for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){ |
527 |
1/1✓ Branch 2 taken 4 times.
|
4 | Node<T, UIdx> * nodeParent = getNode(*it); |
528 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if(nodeParent != NULL){ |
529 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if(!nodeParent->getIsUpdated()){ |
530 | //The parent node is added only if its children are updated | ||
531 |
2/3✓ Branch 2 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | if(isListNodeUdpated(nodeParent->getListChild())){ |
532 |
1/1✓ Branch 2 taken 4 times.
|
4 | mapListParent[*it] = true; |
533 | 4 | nodeParent->setIsUpdated(true); | |
534 | } | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | } | ||
540 | 3 | std::list<UIdx> listNodeOut; | |
541 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 3 times.
|
7 | for(typename std::map<UIdx, bool>::iterator it(mapListParent.begin()); it != mapListParent.end(); ++it){ |
542 |
1/1✓ Branch 2 taken 4 times.
|
4 | listNodeOut.push_back(it->first); |
543 | } | ||
544 |
1/1✓ Branch 1 taken 3 times.
|
3 | listNode = listNodeOut; |
545 | 3 | } | |
546 | 4 | return listNode.size() != 0lu; | |
547 | } | ||
548 | |||
549 | ///Copy function of Graph | ||
550 | /** @param other : class to copy | ||
551 | */ | ||
552 | template<typename T, typename UIdx> | ||
553 | 1 | void Graph<T, UIdx>::copyGraph(const Graph<T, UIdx> & other){ | |
554 | 1 | p_mapNode = other.p_mapNode; | |
555 | 1 | p_listFirstNode = other.p_listFirstNode; | |
556 | 1 | p_listLastNode = other.p_listLastNode; | |
557 | 1 | } | |
558 | |||
559 | ///Initialisation function of the class Graph | ||
560 | template<typename T, typename UIdx> | ||
561 | 5 | void Graph<T, UIdx>::initialisationGraph(){ | |
562 | |||
563 | 5 | } | |
564 | |||
565 | |||
566 | |||
567 | |||
568 | |||
569 | #endif | ||
570 | |||
571 | |||
572 | |||
573 |