Merge lp:~tapaal-dist-ctl/verifypn/ParserRefactoring_The_Correct_One into lp:~verifypn-maintainers/verifypn/trunk

Proposed by Søren Moss Nielsen
Status: Merged
Approved by: Jiri Srba
Approved revision: 114
Merged at revision: 90
Proposed branch: lp:~tapaal-dist-ctl/verifypn/ParserRefactoring_The_Correct_One
Merge into: lp:~verifypn-maintainers/verifypn/trunk
Diff against target: 12960 lines (+12094/-450)
22 files modified
CTL/CertainZeroFPA.cpp (+3/-23)
CTL/CertainZeroFPA.h (+1/-1)
CTL/DependencyGraph.cpp (+1/-1)
CTL/DependencyGraph.h (+3/-2)
CTL/LocalFPA.h (+1/-1)
CTL/OnTheFlyDG.cpp (+352/-373)
CTL/OnTheFlyDG.h (+6/-3)
CTL/configuration.cpp (+5/-4)
CTL/configuration.h (+5/-3)
CTL/edge.cpp (+1/-1)
CTLParser/CTLOptimizer.cpp (+77/-0)
CTLParser/CTLOptimizer.h (+31/-0)
CTLParser/CTLParser.cpp (+0/-1)
CTLParser/CTLParser_v2.cpp (+508/-0)
CTLParser/CTLParser_v2.h (+56/-0)
CTLParser/CTLQuery.cpp (+159/-0)
CTLParser/CTLQuery.h (+66/-0)
CTLParser/EvaluateableProposition.cpp (+189/-0)
CTLParser/EvaluateableProposition.h (+53/-0)
Tests/unitTesting/catch.hpp (+10483/-0)
VerifyPN.cpp (+93/-36)
makefile.linux64 (+1/-1)
To merge this branch: bzr merge lp:~tapaal-dist-ctl/verifypn/ParserRefactoring_The_Correct_One
Reviewer Review Type Date Requested Status
Jiri Srba Approve
Review via email: mp+295287@code.launchpad.net

Commit message

Refactored parser for CTL queries.

Description of the change

The fixed requested have been implemented

To post a comment you must log in.
Revision history for this message
Jiri Srba (srba) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CTL/CertainZeroFPA.cpp'
2--- CTL/CertainZeroFPA.cpp 2016-04-12 08:29:03 +0000
3+++ CTL/CertainZeroFPA.cpp 2016-05-20 07:41:18 +0000
4@@ -2,34 +2,12 @@
5
6 namespace ctl{
7
8-bool preprocessQuery(CTLTree *f) {
9-
10- bool isTemporal = f->quantifier == A || f->quantifier == E;
11- if (f->quantifier == AND ||
12- f->quantifier == OR ||
13- (f->quantifier == A && f->path == U) ||
14- (f->quantifier == E && f->path == U)) {
15- //operand order guarantees subquery will be preprocessed
16- isTemporal = preprocessQuery(f->second) || isTemporal;
17- isTemporal = preprocessQuery(f->first) || isTemporal;
18- }
19- if (f->quantifier == NEG ||
20- (f->path == G && (f->quantifier == A || f->quantifier == E)) ||
21- (f->path == X && (f->quantifier == A || f->quantifier == E)) ||
22- (f->path == F && (f->quantifier == A || f->quantifier == E))) {
23- isTemporal = preprocessQuery(f->first) || isTemporal;
24- }
25- f->isTemporal = isTemporal;
26- return isTemporal;
27-}
28-
29 bool CertainZeroFPA::search(DependencyGraph &t_graph, AbstractSearchStrategy &W)
30 {
31 PriorityQueue N;
32
33 Configuration &v = t_graph.initialConfiguration();
34 v.assignment = ZERO;
35- preprocessQuery(v.query);
36
37 for(Edge *e : t_graph.successors(v)){
38 W.push(e);
39@@ -48,6 +26,8 @@
40 N.pop();
41 }
42
43+// e->edgePrinter();
44+
45 /*****************************************************************/
46 /*Data handling*/
47 int targetONEassignments = 0;
48@@ -156,7 +136,7 @@
49 e->processed = true;
50 }
51
52- //std::cout << "Final Assignment: " << v.assignment << " " << ((v.assignment == ONE) ? true : false) << std::endl;
53+// std::cout << "Final Assignment: " << v.assignment << " " << ((v.assignment == ONE) ? true : false) << std::endl;
54 return (v.assignment == ONE) ? true : false;
55 }
56
57
58=== modified file 'CTL/CertainZeroFPA.h'
59--- CTL/CertainZeroFPA.h 2016-02-08 18:27:31 +0000
60+++ CTL/CertainZeroFPA.h 2016-05-20 07:41:18 +0000
61@@ -19,7 +19,7 @@
62 private:
63 struct edge_prioritizer{
64 bool operator()(const Edge *lhs, const Edge *rhs) const {
65- return (lhs->source->query->max_depth > rhs->source->query->max_depth);
66+ return (lhs->source->query->Depth > rhs->source->query->Depth); //Changed to depth - was max depth
67 }
68 };
69 typedef std::priority_queue<Edge*, std::vector<Edge*>, ctl::CertainZeroFPA::edge_prioritizer> PriorityQueue;
70
71=== modified file 'CTL/DependencyGraph.cpp'
72--- CTL/DependencyGraph.cpp 2016-03-31 11:56:31 +0000
73+++ CTL/DependencyGraph.cpp 2016-05-20 07:41:18 +0000
74@@ -10,7 +10,7 @@
75 _nplaces(t_net->numberOfPlaces()),
76 _ntransitions(t_net->numberOfTransitions()){}
77
78-void DependencyGraph::initialize(CTLTree &t_query){
79+void DependencyGraph::initialize(CTLQuery &t_query){
80 if(_query != NULL)
81 clear(false);
82 _query = &t_query;
83
84=== modified file 'CTL/DependencyGraph.h'
85--- CTL/DependencyGraph.h 2016-04-13 14:36:41 +0000
86+++ CTL/DependencyGraph.h 2016-05-20 07:41:18 +0000
87@@ -4,6 +4,7 @@
88 #include "../PetriEngine/PetriNet.h"
89 #include "../PetriParse/PNMLParser.h"
90 #include "../CTLParser/CTLParser.h"
91+#include "../CTLParser/CTLQuery.h"
92 #include <list>
93 #include <iostream>
94
95@@ -28,10 +29,10 @@
96 virtual int configuration_count() =0;
97 virtual int marking_count() =0;
98
99- void initialize(CTLTree &t_query);
100+ void initialize(CTLQuery &t_query);
101
102 protected:
103- CTLTree *_query = nullptr;
104+ CTLQuery *_query = nullptr;
105 PetriEngine::PetriNet *_petriNet;
106 PetriEngine::MarkVal *_initialMarking;
107 PNMLParser::InhibitorArcList _inhibitorArcs;
108
109=== modified file 'CTL/LocalFPA.h'
110--- CTL/LocalFPA.h 2016-02-08 18:27:31 +0000
111+++ CTL/LocalFPA.h 2016-05-20 07:41:18 +0000
112@@ -19,7 +19,7 @@
113 private:
114 struct edge_prioritizer{
115 bool operator()(const Edge *lhs, const Edge *rhs) const {
116- return (lhs->source->query->max_depth > rhs->source->query->max_depth);
117+ return (lhs->source->query->Depth > rhs->source->query->Depth); //Changed to depth - was max depth
118 }
119 };
120 typedef std::priority_queue<Edge*, std::vector<Edge*>, ctl::LocalFPA::edge_prioritizer> PriorityQueue;
121
122=== modified file 'CTL/OnTheFlyDG.cpp'
123--- CTL/OnTheFlyDG.cpp 2016-04-14 12:15:28 +0000
124+++ CTL/OnTheFlyDG.cpp 2016-05-20 07:41:18 +0000
125@@ -1,6 +1,7 @@
126 #include "OnTheFlyDG.h"
127
128 #include <string.h>
129+#include <algorithm>
130
131 namespace ctl{
132
133@@ -12,336 +13,322 @@
134 }
135
136
137-bool OnTheFlyDG::fastEval(CTLTree &query, Marking &marking) {
138- assert(!query.isTemporal);
139- if (query.quantifier == AND){
140- return fastEval(*query.first, marking) && fastEval(*query.second, marking);
141- } else if (query.quantifier == OR){
142- return fastEval(*query.first, marking) || fastEval(*query.second, marking);
143- } else if (query.quantifier == NEG){
144- return !fastEval(*query.first, marking);
145- } else {
146- return evaluateQuery(query, marking);
147+bool OnTheFlyDG::fastEval(CTLQuery &query, Marking &marking) {
148+ assert(!query.IsTemporal);
149+ if (query.GetQuantifier() == AND){
150+ return fastEval(*query.GetFirstChild(), marking) && fastEval(*query.GetSecondChild(), marking);
151+ } else if (query.GetQuantifier() == OR){
152+ return fastEval(*query.GetFirstChild(), marking) || fastEval(*query.GetSecondChild(), marking);
153+ } else if (query.GetQuantifier() == NEG){
154+ bool result = fastEval(*query.GetFirstChild(), marking);
155+ return !result;
156+ } else {
157+ bool res = evaluateQuery(query, marking);
158+ return res;
159 }
160 }
161
162 std::list<Edge *> OnTheFlyDG::successors(Configuration &v)
163 {
164 std::list<Edge*> succ;
165- //All
166- if(v.query->quantifier == A){
167- //All Until
168- if(v.query->path == U){
169- //first deal with the right side
170- Edge *right = NULL;
171- if (!v.query->second->isTemporal) {
172- //right side is not temporal, eval it right now!
173- bool valid = fastEval(*(v.query->second), *(v.marking));
174- if (valid) { //satisfied, no need to go through successors
175- succ.push_back(new Edge(&v));
176- v.Successors = succ;
177- return succ;
178- } //else: It's not valid, no need to add any edge, just add successors
179- } else {
180- //right side is temporal, we need to evaluate it as normal
181- Configuration* c = createConfiguration(*(v.marking), *(v.query->second));
182- right = new Edge(&v);
183- right->targets.push_back(c);
184- }
185-
186- //if we got here, either right side is temporal or it is not satisfied
187- bool valid = false;
188- Configuration *left = NULL;
189- if (!v.query->first->isTemporal) {
190- //left side is not temporal, eval it right now!
191- valid = fastEval(*(v.query->first), *(v.marking));
192- } else {
193- //left side is temporal, include it in the edge
194- left = createConfiguration(*(v.marking), *(v.query->first));
195- }
196-
197- if (valid || left != NULL) { //if left side is guaranteed to be not satisfied, skip successor generation
198- auto targets = nextState (*(v.marking));
199-
200- if(!targets.empty()){
201- Edge* leftEdge = new Edge(&v);
202-
203- for(auto m : targets){
204- Configuration* c = createConfiguration(*m, *(v.query));
205- leftEdge->targets.push_back(c);
206- }
207- if (left != NULL) {
208- leftEdge->targets.push_back(left);
209- }
210- succ.push_back(leftEdge);
211- }
212- } //else: Left side is not temporal and it's false, no way to succeed there...
213-
214- if (right != NULL) {
215- succ.push_back(right);
216- }
217-
218-
219- } //All Until end
220-
221- //All Next begin
222- else if(v.query->path == X){
223- auto targets = nextState(*v.marking);
224- if (v.query->first->isTemporal) { //regular check
225- Edge* e = new Edge(&v);
226- for (auto m : targets){
227- Configuration* c = createConfiguration(*m, *(v.query->first));
228- e->targets.push_back(c);
229- }
230- succ.push_back(e);
231- } else {
232- bool allValid = true;
233- for (auto m : targets) {
234- bool valid = fastEval(*(v.query->first), *m);
235- if (!valid) {
236- allValid = false;
237- break;
238- }
239- }
240- if (allValid) {
241- succ.push_back(new Edge(&v));
242- v.Successors = succ;
243- return succ;
244- }
245- }
246- } //All Next End
247-
248- //All Finally start
249- else if(v.query->path == F){
250- Edge *subquery = NULL;
251- if (!v.query->first->isTemporal) {
252- bool valid = fastEval(*(v.query->first), *(v.marking));
253- if (valid) {
254- succ.push_back(new Edge(&v));
255- v.Successors = succ;
256- return succ;
257- }
258- } else {
259- subquery = new Edge(&v);
260- Configuration* c = createConfiguration(*(v.marking), *(v.query->first));
261- subquery->targets.push_back(c);
262- }
263-
264- auto targets = nextState(*(v.marking));
265-
266- if(!targets.empty()){
267- Edge* e1 = new Edge(&v);
268-
269- for(auto m : targets){
270- Configuration* c = createConfiguration(*m, *(v.query));
271- e1->targets.push_back(c);
272- }
273- succ.push_back(e1);
274- }
275-
276- if (subquery != NULL) {
277- succ.push_back(subquery);
278- }
279-
280- }//All Finally end
281- } //All end
282-
283- //Exists start
284- else if (v.query->quantifier == E){
285-
286- //Exists Untill start
287- if(v.query->path == U){
288- Edge *right = NULL;
289- if (v.query->second->isTemporal) {
290- Configuration* c = createConfiguration(*(v.marking), *(v.query->second));
291- right = new Edge(&v);
292- right->targets.push_back(c);
293- } else {
294- bool valid = fastEval(*(v.query->second), *(v.marking));
295- if (valid) {
296- succ.push_back(new Edge(&v));
297- v.Successors = succ;
298- return succ;
299- } // else: right condition is not satisfied, no need to add an edge
300- }
301-
302- auto targets = nextState(*(v.marking));
303-
304- if(!targets.empty()){
305+ CTLType query_type = v.query->GetQueryType();
306+ if(query_type == EVAL){
307+ //assert(false && "Someone told me, this was a bad place to be.");
308+ if (evaluateQuery(*v.query, *v.marking)){
309+ succ.push_back(new Edge(&v));
310+ }
311+ }
312+ else if (query_type == LOPERATOR){
313+ if(v.query->GetQuantifier() == NEG){
314+ Configuration* c = createConfiguration(*(v.marking), *(v.query->GetFirstChild()));
315+ Edge* e = new Edge(&v);
316+ e->targets.push_back(c);
317+ succ.push_back(e);
318+ }
319+ else if(v.query->GetQuantifier() == AND){
320+ //Check if left is false
321+ if(!v.query->GetFirstChild()->IsTemporal){
322+ if(!fastEval(*(v.query->GetFirstChild()), *v.marking))
323+ //query cannot be satisfied, return empty succ set
324+ return succ;
325+ }
326+
327+ //check if right is false
328+ if(!v.query->GetSecondChild()->IsTemporal){
329+ if(!fastEval(*(v.query->GetSecondChild()), *v.marking))
330+ return succ;
331+ }
332+
333+ Edge *e = new Edge(&v);
334+
335+ //If we get here, then either both propositions are true(should not be possible)
336+ //Or a temporal operator and a true proposition
337+ //Or both are temporal
338+ if(v.query->GetFirstChild()->IsTemporal){
339+ e->targets.push_back(createConfiguration(*v.marking, *(v.query->GetFirstChild())));
340+ }
341+ if(v.query->GetSecondChild()->IsTemporal){
342+ e->targets.push_back(createConfiguration(*v.marking, *(v.query->GetSecondChild())));
343+ }
344+ succ.push_back(e);
345+ }
346+ else if(v.query->GetQuantifier() == OR){
347+ //Check if left is true
348+ if(!v.query->GetFirstChild()->IsTemporal){
349+ if(fastEval(*(v.query->GetFirstChild()), *v.marking)){
350+ //query is satisfied, return
351+ succ.push_back(new Edge(&v));
352+ v.Successors = succ;
353+ return succ;
354+ }
355+ }
356+
357+ if(!v.query->GetSecondChild()->IsTemporal){
358+ if(fastEval(*(v.query->GetSecondChild()), *v.marking)){
359+ succ.push_back(new Edge(&v));
360+ v.Successors = succ;
361+ return succ;
362+ }
363+ }
364+
365+ //If we get here, either both propositions are false
366+ //Or one is false and one is temporal
367+ //Or both temporal
368+ if(v.query->GetFirstChild()->IsTemporal){
369+ Edge *e = new Edge(&v);
370+ e->targets.push_back(createConfiguration(*v.marking, *(v.query->GetFirstChild())));
371+ succ.push_back(e);
372+ }
373+ if(v.query->GetSecondChild()->IsTemporal){
374+ Edge *e = new Edge(&v);
375+ e->targets.push_back(createConfiguration(*v.marking, *(v.query->GetSecondChild())));
376+ succ.push_back(e);
377+ }
378+ }
379+ else{
380+ assert(false && "An unknown error occoured in the loperator-part of the successor generator");
381+ }
382+ }
383+ else if (query_type == PATHQEURY){
384+ if(v.query->GetQuantifier() == A){
385+ if (v.query->GetPath() == U){
386+ Edge *right = NULL;
387+ if (!v.query->GetSecondChild()->IsTemporal){
388+ //right side is not temporal, eval it right now!
389+ bool valid = fastEval(*(v.query->GetSecondChild()), *(v.marking));
390+ if (valid) { //satisfied, no need to go through successors
391+ succ.push_back(new Edge(&v));
392+ v.Successors = succ;
393+ return succ;
394+ }//else: It's not valid, no need to add any edge, just add successors
395+ }
396+ else {
397+ //right side is temporal, we need to evaluate it as normal
398+ Configuration* c = createConfiguration(*(v.marking), *(v.query->GetSecondChild()));
399+ right = new Edge(&v);
400+ right->targets.push_back(c);
401+ }
402+ bool valid = false;
403 Configuration *left = NULL;
404- bool valid = false;
405- if (v.query->first->isTemporal) {
406- left = createConfiguration(*(v.marking), *(v.query->first));
407+ if (!v.query->GetFirstChild()->IsTemporal) {
408+ //left side is not temporal, eval it right now!
409+ valid = fastEval(*(v.query->GetFirstChild()), *(v.marking));
410 } else {
411- valid = fastEval(*(v.query->first), *(v.marking));
412- }
413- if (left != NULL || valid) {
414- for(auto m : targets) {
415- Edge* e = new Edge(&v);
416- Configuration* c1 = createConfiguration(*m, *(v.query));
417- e->targets.push_back(c1);
418+ //left side is temporal, include it in the edge
419+ left = createConfiguration(*(v.marking), *(v.query->GetFirstChild()));
420+ }
421+ if (valid || left != NULL) { //if left side is guaranteed to be not satisfied, skip successor generation
422+ auto targets = nextState (*(v.marking));
423+
424+ if(!targets.empty()){
425+ Edge* leftEdge = new Edge(&v);
426+
427+ for(auto m : targets){
428+ Configuration* c = createConfiguration(*m, *(v.query));
429+ leftEdge->targets.push_back(c);
430+ }
431 if (left != NULL) {
432- e->targets.push_back(left);
433- }
434- succ.push_back(e);
435+ leftEdge->targets.push_back(left);
436+ }
437+ succ.push_back(leftEdge);
438 }
439+ } //else: Left side is not temporal and it's false, no way to succeed there...
440+
441+ if (right != NULL) {
442+ succ.push_back(right);
443 }
444 }
445-
446- if (right != NULL) {
447- succ.push_back(right);
448- }
449-
450- } //Exists Until end
451-
452- //Exists Next start
453- else if(v.query->path == X){
454- auto targets = nextState(*(v.marking));
455- CTLTree* query = v.query->first;
456-
457- if(!targets.empty())
458- {
459- if (query->isTemporal) { //have to check, no way to skip that
460- for(auto m : targets){
461- Edge* e = new Edge(&v);
462- Configuration* c = createConfiguration(*m, *query);
463- e->targets.push_back(c);
464- succ.push_back(e);
465- }
466+ else if(v.query->GetPath() == F){
467+ Edge *subquery = NULL;
468+ if (!v.query->GetFirstChild()->IsTemporal) {
469+ bool valid = fastEval(*(v.query->GetFirstChild()), *(v.marking));
470+ if (valid) {
471+ succ.push_back(new Edge(&v));
472+ v.Successors = succ;
473+ return succ;
474+ }
475 } else {
476- for(auto m : targets) {
477- bool valid = fastEval(*query, *m);
478- if (valid) {
479- succ.push_back(new Edge(&v));
480- v.Successors = succ;
481- return succ;
482- } //else: It can't hold there, no need to create an edge
483+ subquery = new Edge(&v);
484+ Configuration* c = createConfiguration(*(v.marking), *(v.query->GetFirstChild()));
485+ subquery->targets.push_back(c);
486+ }
487+
488+ auto targets = nextState(*(v.marking));
489+
490+ if(!targets.empty()){
491+ Edge* e1 = new Edge(&v);
492+
493+ for(auto m : targets){
494+ Configuration* c = createConfiguration(*m, *(v.query));
495+ e1->targets.push_back(c);
496 }
497- }
498- }
499- }//Exists Next end
500-
501- //Exists Finally start
502- else if(v.query->path == F){
503- Edge *subquery = NULL;
504- if (!v.query->first->isTemporal) {
505- bool valid = fastEval(*(v.query->first), *(v.marking));
506- if (valid) {
507- succ.push_back(new Edge(&v));
508- v.Successors = succ;
509- return succ;
510- }
511- } else {
512- Configuration* c = createConfiguration(*(v.marking), *(v.query->first));
513- subquery = new Edge(&v);
514- subquery->targets.push_back(c);
515- }
516-
517- auto targets = nextState(*(v.marking));
518-
519- if(!targets.empty()){
520- for(auto m : targets){
521+ succ.push_back(e1);
522+ }
523+
524+ if (subquery != NULL) {
525+ succ.push_back(subquery);
526+ }
527+ }
528+ else if(v.query->GetPath() == X){
529+ auto targets = nextState(*v.marking);
530+ if (v.query->GetFirstChild()->IsTemporal) { //regular check
531 Edge* e = new Edge(&v);
532- Configuration* c = createConfiguration(*m, *(v.query));
533- e->targets.push_back(c);
534+ for (auto m : targets){
535+ Configuration* c = createConfiguration(*m, *(v.query->GetFirstChild()));
536+ e->targets.push_back(c);
537+ }
538 succ.push_back(e);
539- }
540- }
541-
542- if (subquery != NULL) {
543- succ.push_back(subquery);
544- }
545- }//Exists Finally end
546- } //Exists end
547-
548- //And start
549- else if (v.query->quantifier == AND){
550-
551- //Check if left is false
552- if(!v.query->first->isTemporal){
553- if(!fastEval(*(v.query->first), *v.marking))
554- //query cannot be satisfied, return empty succ set
555- return succ;
556- }
557-
558- //check if right is false
559- if(!v.query->second->isTemporal){
560- if(!fastEval(*(v.query->second), *v.marking))
561- return succ;
562- }
563-
564- Edge *e = new Edge(&v);
565-
566- //If we get here, then either both propositions are true(should not be possible)
567- //Or a temporal operator and a true proposition
568- //Or both are temporal
569- if(v.query->first->isTemporal){
570- e->targets.push_back(createConfiguration(*v.marking, *(v.query->first)));
571- }
572- if(v.query->second->isTemporal){
573- e->targets.push_back(createConfiguration(*v.marking, *(v.query->second)));
574- }
575- succ.push_back(e);
576- } //And end
577-
578- //Or start
579- else if (v.query->quantifier == OR){
580-
581- //Check if left is true
582- if(!v.query->first->isTemporal){
583- if(fastEval(*(v.query->first), *v.marking)){
584- //query is satisfied, return
585- succ.push_back(new Edge(&v));
586- v.Successors = succ;
587- return succ;
588- }
589- }
590-
591- if(!v.query->second->isTemporal){
592- if(fastEval(*(v.query->second), *v.marking)){
593- succ.push_back(new Edge(&v));
594- v.Successors = succ;
595- return succ;
596- }
597- }
598-
599- //If we get here, either both propositions are false
600- //Or one is false and one is temporal
601- //Or both temporal
602- if(v.query->first->isTemporal){
603- Edge *e = new Edge(&v);
604- e->targets.push_back(createConfiguration(*v.marking, *(v.query->first)));
605- succ.push_back(e);
606- }
607- if(v.query->second->isTemporal){
608- Edge *e = new Edge(&v);
609- e->targets.push_back(createConfiguration(*v.marking, *(v.query->second)));
610- succ.push_back(e);
611- }
612- } //Or end
613-
614- //Negate start
615- else if (v.query->quantifier == NEG){
616- Configuration* c = createConfiguration(*(v.marking), *(v.query->first));
617- Edge* e = new Edge(&v);
618- e->targets.push_back(c);
619- succ.push_back(e);
620- } //Negate end
621-
622- //Evaluate Query Begin
623- else {
624- //We should never get here anymore.
625- //v.configPrinter();
626- //assert(false);
627- if (evaluateQuery(*v.query, *v.marking)){
628- succ.push_back(new Edge(&v));
629- }
630+ } else {
631+ bool allValid = true;
632+ for (auto m : targets) {
633+ bool valid = fastEval(*(v.query->GetFirstChild()), *m);
634+ if (!valid) {
635+ allValid = false;
636+ break;
637+ }
638+ }
639+ if (allValid) {
640+ succ.push_back(new Edge(&v));
641+ v.Successors = succ;
642+ return succ;
643+ }
644+ }
645+ }
646+ else if(v.query->GetPath() == G ){
647+ assert(false && "Path operator G had not been translated - Parse error detected in succ()");
648+ }
649+ else
650+ assert(false && "An unknown error occoured in the successor generator");
651+ }
652+ else if(v.query->GetQuantifier() == E){
653+ if (v.query->GetPath() == U){
654+ Edge *right = NULL;
655+ if (v.query->GetSecondChild()->IsTemporal) {
656+ Configuration* c = createConfiguration(*(v.marking), *(v.query->GetSecondChild()));
657+ right = new Edge(&v);
658+ right->targets.push_back(c);
659+ } else {
660+ bool valid = fastEval(*(v.query->GetSecondChild()), *(v.marking));
661+ if (valid) {
662+ succ.push_back(new Edge(&v));
663+ v.Successors = succ;
664+ return succ;
665+ } // else: right condition is not satisfied, no need to add an edge
666+ }
667+
668+ auto targets = nextState(*(v.marking));
669+
670+ if(!targets.empty()){
671+ Configuration *left = NULL;
672+ bool valid = false;
673+ if (v.query->GetFirstChild()->IsTemporal) {
674+ left = createConfiguration(*(v.marking), *(v.query->GetFirstChild()));
675+ } else {
676+ valid = fastEval(*(v.query->GetFirstChild()), *(v.marking));
677+ }
678+ if (left != NULL || valid) {
679+ for(auto m : targets) {
680+ Edge* e = new Edge(&v);
681+ Configuration* c1 = createConfiguration(*m, *(v.query));
682+ e->targets.push_back(c1);
683+ if (left != NULL) {
684+ e->targets.push_back(left);
685+ }
686+ succ.push_back(e);
687+ }
688+ }
689+ }
690+
691+ if (right != NULL) {
692+ succ.push_back(right);
693+ }
694+ }
695+ else if(v.query->GetPath() == F){
696+ Edge *subquery = NULL;
697+ if (!v.query->GetFirstChild()->IsTemporal) {
698+ bool valid = fastEval(*(v.query->GetFirstChild()), *(v.marking));
699+ if (valid) {
700+ succ.push_back(new Edge(&v));
701+ v.Successors = succ;
702+ return succ;
703+ }
704+ } else {
705+ Configuration* c = createConfiguration(*(v.marking), *(v.query->GetFirstChild()));
706+ subquery = new Edge(&v);
707+ subquery->targets.push_back(c);
708+ }
709+
710+ auto targets = nextState(*(v.marking));
711+
712+ if(!targets.empty()){
713+ for(auto m : targets){
714+ Edge* e = new Edge(&v);
715+ Configuration* c = createConfiguration(*m, *(v.query));
716+ e->targets.push_back(c);
717+ succ.push_back(e);
718+ }
719+ }
720+
721+ if (subquery != NULL) {
722+ succ.push_back(subquery);
723+ }
724+ }
725+ else if(v.query->GetPath() == X){
726+ auto targets = nextState(*(v.marking));
727+ CTLQuery* query = v.query->GetFirstChild();
728+
729+ if(!targets.empty())
730+ {
731+ if (query->IsTemporal) { //have to check, no way to skip that
732+ for(auto m : targets){
733+ Edge* e = new Edge(&v);
734+ Configuration* c = createConfiguration(*m, *query);
735+ e->targets.push_back(c);
736+ succ.push_back(e);
737+ }
738+ } else {
739+ for(auto m : targets) {
740+ bool valid = fastEval(*query, *m);
741+ if (valid) {
742+ succ.push_back(new Edge(&v));
743+ v.Successors = succ;
744+ return succ;
745+ } //else: It can't hold there, no need to create an edge
746+ }
747+ }
748+ }
749+ }
750+ else if(v.query->GetPath() == G ){
751+ assert(false && "Path operator G had not been translated - Parse error detected in succ()");
752+ }
753+ else
754+ assert(false && "An unknown error occoured in the successor generator");
755+ }
756+
757 }
758-
759+
760 v.Successors = succ;
761 return succ;
762- //computedSucc += succ.size();
763- //std::cout << "-----------EDGES NOW : " << computedSucc << "\n" << std::flush;
764 }
765
766 Configuration &OnTheFlyDG::initialConfiguration()
767@@ -351,69 +338,61 @@
768 return *initial;
769 }
770
771-bool OnTheFlyDG::evaluateQuery(CTLTree &query, Marking &marking){
772-
773- bool result = false;
774-
775- if (query.a.isFireable) {
776+bool OnTheFlyDG::evaluateQuery(CTLQuery &query, Marking &marking){
777+ assert(query.GetQueryType() == EVAL);
778+ EvaluateableProposition *proposition = query.GetProposition();
779+
780+ if (proposition->GetPropositionType() == FIREABILITY) {
781 std::list<int> transistions = calculateFireableTransistions(marking);
782-
783- for (auto t : transistions) {
784- int fs_transition = 0;
785- for(fs_transition = 0; fs_transition < query.a.firesize; fs_transition++){
786- int dpc_place = 0;
787- int truedependencyplaces = 0;
788- for (dpc_place = 0; dpc_place < query.a.fireset[fs_transition].sizeofdenpencyplaces; dpc_place++){
789-
790- if((query.a.fireset[fs_transition].denpencyplaces[dpc_place].intSmaller - 1) < marking[query.a.fireset[fs_transition].denpencyplaces[dpc_place].placeLarger]){
791- //std::cout<<_net->placeNames()[query->a.fireset[fs_transition].denpencyplaces[dpc_place].placeLarger]<<" is true"<<std::endl;
792- truedependencyplaces++;
793- }
794- }
795- if (truedependencyplaces == query.a.fireset[fs_transition].sizeofdenpencyplaces){
796- result = true;
797- }
798+ std::list<int>::iterator it;
799+ transistions.sort();
800+
801+ for(const auto f : proposition->GetFireset()){
802+ it = std::find(transistions.begin(), transistions.end(), f);
803+ if(it != transistions.end()){
804+ return true;
805 }
806 }
807- return result;
808- }
809-
810- ///std::cout<<"Evaluating cardinality... "<<std::endl;
811- // t_config.configPrinter();
812- // std::cout<<"Less: ";
813- int less = query.a.cardinality.intSmaller;
814- int greater= query.a.cardinality.intLarger;
815- if( less == -1 ){
816- int i = 0;
817- less = 0;
818- for (i = 0; i < query.a.cardinality.placeSmaller.sizeoftokencount; i++){
819- int index = query.a.cardinality.placeSmaller.cardinality[i];
820- less += marking[index];
821- // std::cout<<t_config.marking->Value()[index]<<" + ";
822- }
823- }
824-// std::cout<<" = "<<less<<std::endl;
825-// std::cout<<"Greater: ";
826- if (greater == -1){
827- int i = 0;
828- greater = 0;
829- // std::cout<<"::: Number of places: "<<query->a.cardinality.placeLarger.sizeoftokencount<<std::endl;
830- for (i = 0; i < query.a.cardinality.placeLarger.sizeoftokencount; i++){
831- //std::cout<<"::::: i: "<<i<<std::endl;
832- int index = query.a.cardinality.placeLarger.cardinality[i];
833- //std::cout<<"::::: Index: "<<index<<" - Value: "<<t_config.marking->Value()[index]<<std::endl;
834- greater += marking[index];
835- // std::cout<<t_config.marking->Value()[index]<<" + ";
836- // std::cout<<"::::: greater: "<<greater<<std::endl;
837- }
838-
839- }
840- // std::cout<<" = "<<greater<<std::endl;
841-
842- result = less <= greater;
843- // std::cout<<"... evaluation Done"<<std::endl;
844- return result;
845-}
846+ return false;
847+ }
848+ else if (proposition->GetPropositionType() == CARDINALITY){
849+ int first_param = GetParamValue(proposition->GetFirstParameter(), marking);
850+ int second_param = GetParamValue(proposition->GetSecondParameter(), marking);
851+ return EvalCardianlity(first_param, proposition->GetLoperator(), second_param);
852+ }
853+ else
854+ assert(false && "Incorrect query proposition type was attempted evaluated");
855+
856+}
857+
858+int OnTheFlyDG::GetParamValue(CardinalityParameter *param, Marking& marking) {
859+ if(param->isPlace){
860+ int res = 0;
861+ for(int place : param->places_i){
862+ res = res + marking.Value()[place];
863+ }
864+ return res;
865+ }
866+ else{
867+ return param->value;
868+ }
869+}
870+
871+bool OnTheFlyDG::EvalCardianlity(int a, LoperatorType lop, int b) {
872+ if(lop == EQ)
873+ return a == b;
874+ else if (lop == LE)
875+ return a < b;
876+ else if (lop == LEQ)
877+ return a <= b;
878+ else if (lop == GR)
879+ return a > b;
880+ else if (lop == GRQ)
881+ return a >= b;
882+ assert(false && "Unsupported LOperator attemped evaluated");
883+}
884+
885+
886
887 int OnTheFlyDG::indexOfPlace(char *t_place){
888 for (int i = 0; i < _nplaces; i++) {
889@@ -522,7 +501,7 @@
890 }
891 }
892
893-Configuration *OnTheFlyDG::createConfiguration(Marking &t_marking, CTLTree &t_query)
894+Configuration *OnTheFlyDG::createConfiguration(Marking &t_marking, CTLQuery &t_query)
895 {
896 for(Configuration* c : t_marking.successors){
897 if(c->query == &t_query)
898@@ -534,7 +513,7 @@
899 newConfig->query = &t_query;
900
901 //Default value is false
902- if(t_query.quantifier == NEG){
903+ if(t_query.GetQueryType() == LOPERATOR && t_query.GetQuantifier() == NEG){
904 newConfig->IsNegated = true;
905 }
906
907
908=== modified file 'CTL/OnTheFlyDG.h'
909--- CTL/OnTheFlyDG.h 2016-04-14 12:15:28 +0000
910+++ CTL/OnTheFlyDG.h 2016-05-20 07:41:18 +0000
911@@ -34,19 +34,22 @@
912 // boost::hash<Configuration*>,
913 // Configuration::Configuration_Equal_To> Configurations;
914 bool isCompressing() {return _compressoption;}
915+private:
916+ int GetParamValue(CardinalityParameter *param, Marking &marking);
917+ bool EvalCardianlity(int a, LoperatorType lop, int b);
918
919 protected:
920 Marking *cached_marking = nullptr;
921 std::vector<Marking*> cached_successors;
922
923- bool evaluateQuery(CTLTree &query, Marking &marking);
924+ bool evaluateQuery(CTLQuery &query, Marking &marking);
925 bool _compressoption;
926 int indexOfPlace(char *t_place);
927 std::vector<Marking *> nextState(Marking &t_marking);
928 std::list<int> calculateFireableTransistions(Marking &t_marking);
929- Configuration *createConfiguration(Marking &t_marking, CTLTree &t_query);
930+ Configuration *createConfiguration(Marking &t_marking, CTLQuery &t_query);
931 Marking *createMarking(const Marking &t_marking, int t_transition);
932- bool fastEval(CTLTree &query, Marking &marking);
933+ bool fastEval(CTLQuery &query, Marking &marking);
934
935 void initCompressOption();
936
937
938=== modified file 'CTL/configuration.cpp'
939--- CTL/configuration.cpp 2015-12-08 07:25:27 +0000
940+++ CTL/configuration.cpp 2016-05-20 07:41:18 +0000
941@@ -1,8 +1,9 @@
942 #include "configuration.h"
943+#include "../CTLParser/CTLParser_v2.h"
944
945 namespace ctl{
946
947-Configuration::Configuration(Marking * t_marking, CTLTree * t_query){
948+Configuration::Configuration(Marking * t_marking, CTLQuery * t_query){
949 marking = t_marking;
950 query = t_query;
951 }
952@@ -36,13 +37,13 @@
953
954
955 void Configuration::configPrinter(){
956- CTLParser ctlParser = CTLParser();
957+ CTLParser_v2 ctlParser = CTLParser_v2();
958 int i = 0;
959 std::cout << "Marking: ";
960 marking->print();
961 std::cout << " Q: " << std::flush;
962- ctlParser.printQuery(query);
963- std::cout << " D: "<<query->depth << std::flush;
964+ std::cout << ctlParser.QueryToString(query)<<std::flush;
965+ std::cout << " D: "<<query->Depth << std::flush;
966 std::cout << " Assign: " << assignment << std::flush;
967
968 std::cout << " NEG: " << IsNegated << "\n" << std::flush;
969
970=== modified file 'CTL/configuration.h'
971--- CTL/configuration.h 2016-04-12 10:22:19 +0000
972+++ CTL/configuration.h 2016-05-20 07:41:18 +0000
973@@ -2,6 +2,7 @@
974 #define CONFIGURATION_H
975
976 #include "../CTLParser/CTLParser.h"
977+#include "../CTLParser/CTLQuery.h"
978 #include "marking.h"
979 #include "edge.h"
980 #include <list>
981@@ -26,7 +27,7 @@
982 };
983
984 Configuration(){}
985- Configuration(Marking* t_marking, CTLTree* t_query);
986+ Configuration(Marking* t_marking, CTLQuery* t_query);
987 virtual ~Configuration();
988
989 void removeSuccessor(Edge *t_successor);
990@@ -36,7 +37,7 @@
991 bool operator!=(const Configuration &rhs) const {return !(*this == rhs);}
992
993 Marking* marking;
994- CTLTree* query;
995+ CTLQuery* query;
996 std::list<Edge*> Successors;
997 std::list<Edge*> DependencySet;
998 bool IsNegated = false;
999@@ -60,7 +61,8 @@
1000
1001 return result;*/
1002 long xorHash = ((long) t_config.query) ^ ((long) t_config.marking);
1003- return (size_t) (xorHash ^ (xorHash >> 32));
1004+ //return (size_t) (xorHash ^ (xorHash >> 32)); <-- Only works for 64bit
1005+ return (size_t) (xorHash ^ (xorHash >> ((sizeof(size_t)*8)/2)));
1006 }
1007 };
1008 template<>
1009
1010=== modified file 'CTL/edge.cpp'
1011--- CTL/edge.cpp 2016-01-21 11:38:51 +0000
1012+++ CTL/edge.cpp 2016-05-20 07:41:18 +0000
1013@@ -34,7 +34,7 @@
1014 int beta = 1;
1015 int gamma = 1;
1016
1017- int dist = source->query->depth;
1018+ int dist = source->query->Depth;
1019 int breath = 0;
1020 int succ = source->Successors.size();
1021
1022
1023=== added file 'CTLParser/CTLOptimizer.cpp'
1024--- CTLParser/CTLOptimizer.cpp 1970-01-01 00:00:00 +0000
1025+++ CTLParser/CTLOptimizer.cpp 2016-05-20 07:41:18 +0000
1026@@ -0,0 +1,77 @@
1027+/*
1028+ * To change this license header, choose License Headers in Project Properties.
1029+ * To change this template file, choose Tools | Templates
1030+ * and open the template in the editor.
1031+ */
1032+
1033+/*
1034+ * File: CTLOptimizer.cpp
1035+ * Author: mossns
1036+ *
1037+ * Created on April 28, 2016, 1:54 PM
1038+ */
1039+
1040+#include "CTLOptimizer.h"
1041+
1042+CTLOptimizer::CTLOptimizer() {
1043+}
1044+
1045+CTLOptimizer::CTLOptimizer(const CTLOptimizer& orig) {
1046+}
1047+
1048+CTLOptimizer::~CTLOptimizer() {
1049+}
1050+
1051+CTLQuery* CTLOptimizer::Optimize(CTLQuery *query) {
1052+ query = OptimizeNegation(query);
1053+ return query;
1054+}
1055+
1056+CTLQuery* CTLOptimizer::OptimizeNegation(CTLQuery *query) {
1057+ CTLType query_type = query->GetQueryType();
1058+ if(query_type == EVAL){
1059+ return query;
1060+ }
1061+ else if (query_type == LOPERATOR){
1062+ if(query->GetQuantifier() != NEG){
1063+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1064+ query->SetSecondChild(OptimizeNegation(query->GetSecondChild()));
1065+ }
1066+ else {//Negation
1067+ if(query->GetFirstChild()->GetQueryType() == LOPERATOR && query->GetFirstChild()->GetQuantifier() == NEG){
1068+ query = query->GetFirstChild()->GetFirstChild();
1069+ if(query->GetQueryType() == EVAL){
1070+ return query;
1071+ }
1072+ else if(query->GetQueryType() == LOPERATOR){
1073+ if(query->GetQuantifier() != NEG){
1074+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1075+ query->SetSecondChild(OptimizeNegation(query->GetSecondChild()));
1076+ }
1077+ else{
1078+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1079+ }
1080+ }
1081+ else if (query->GetQueryType() == PATHQEURY){
1082+ if (query->GetPath() == U){
1083+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1084+ query->SetSecondChild(OptimizeNegation(query->GetSecondChild()));
1085+ }
1086+ else{
1087+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1088+ }
1089+ }
1090+ }
1091+ }
1092+ }
1093+ else if (query_type == PATHQEURY){
1094+ if (query->GetPath() == U){
1095+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1096+ query->SetSecondChild(OptimizeNegation(query->GetSecondChild()));
1097+ }
1098+ else{
1099+ query->SetFirstChild(OptimizeNegation(query->GetFirstChild()));
1100+ }
1101+ }
1102+ return query;
1103+}
1104
1105=== added file 'CTLParser/CTLOptimizer.h'
1106--- CTLParser/CTLOptimizer.h 1970-01-01 00:00:00 +0000
1107+++ CTLParser/CTLOptimizer.h 2016-05-20 07:41:18 +0000
1108@@ -0,0 +1,31 @@
1109+/*
1110+ * To change this license header, choose License Headers in Project Properties.
1111+ * To change this template file, choose Tools | Templates
1112+ * and open the template in the editor.
1113+ */
1114+
1115+/*
1116+ * File: CTLOptimizer.h
1117+ * Author: mossns
1118+ *
1119+ * Created on April 28, 2016, 1:54 PM
1120+ */
1121+
1122+#ifndef CTLOPTIMIZER_H
1123+#define CTLOPTIMIZER_H
1124+
1125+#include "CTLQuery.h"
1126+
1127+class CTLOptimizer {
1128+public:
1129+ CTLOptimizer();
1130+ CTLOptimizer(const CTLOptimizer& orig);
1131+ virtual ~CTLOptimizer();
1132+
1133+ CTLQuery * Optimize(CTLQuery *query);
1134+private:
1135+ CTLQuery * OptimizeNegation(CTLQuery *query);
1136+};
1137+
1138+#endif /* CTLOPTIMIZER_H */
1139+
1140
1141=== modified file 'CTLParser/CTLParser.cpp'
1142--- CTLParser/CTLParser.cpp 2016-02-11 13:26:44 +0000
1143+++ CTLParser/CTLParser.cpp 2016-05-20 07:41:18 +0000
1144@@ -35,7 +35,6 @@
1145 #ifdef DEBUG
1146 std::cout << "Creating doc\n" << std::flush;
1147 #endif
1148-// CTLquery ctlquery;
1149 xml_document<> doc;
1150 xml_node<> * root_node;
1151
1152
1153=== added file 'CTLParser/CTLParser_v2.cpp'
1154--- CTLParser/CTLParser_v2.cpp 1970-01-01 00:00:00 +0000
1155+++ CTLParser/CTLParser_v2.cpp 2016-05-20 07:41:18 +0000
1156@@ -0,0 +1,508 @@
1157+/*
1158+ * To change this license header, choose License Headers in Project Properties.
1159+ * To change this template file, choose Tools | Templates
1160+ * and open the template in the editor.
1161+ */
1162+
1163+/*
1164+ * File: CTLParser_v2.cpp
1165+ * Author: mossns
1166+ *
1167+ * Created on April 22, 2016, 10:15 AM
1168+ */
1169+
1170+#include "rapidxml-1.13/rapidxml.hpp"
1171+#include "CTLParser_v2.h"
1172+#include "CTLQuery.h"
1173+#include "EvaluateableProposition.h"
1174+#include <algorithm>
1175+
1176+
1177+using namespace rapidxml;
1178+
1179+CTLParser_v2::CTLParser_v2() {
1180+}
1181+
1182+CTLParser_v2::CTLParser_v2(const CTLParser_v2& orig) {
1183+}
1184+
1185+CTLParser_v2::~CTLParser_v2() {
1186+}
1187+
1188+std::string CTLParser_v2::QueryToString(CTLQuery* query){
1189+ if(query->GetQuantifier() == EMPTY && query->GetPath() == pError){
1190+ return query->GetAtom();
1191+ }
1192+ else if (query->GetPath() == pError){
1193+ Quantifier q = query->GetQuantifier();
1194+ if (q == NEG){
1195+ return query->ToString() + "(" + QueryToString(query->GetFirstChild()) + ")";
1196+ }
1197+ else if (q == AND || q == OR){
1198+ return "(" + QueryToString(query->GetFirstChild()) + query->ToString() + QueryToString(query->GetSecondChild()) + ")";
1199+ }
1200+ else assert(false && "Could not print unknown logical query operator");
1201+ }
1202+ else if(query->GetQuantifier() == A || query->GetQuantifier() == E){
1203+ if(query->GetPath() == U){
1204+ return query->ToString() + "(" + QueryToString(query->GetFirstChild()) + ")Reach(" + QueryToString(query->GetSecondChild()) + ")";
1205+ }
1206+ else{
1207+ return query->ToString() + "(" + QueryToString(query->GetFirstChild()) + ")";
1208+ }
1209+ }
1210+ else assert(false && "Could not print unknown query type");
1211+}
1212+
1213+CTLQuery* CTLParser_v2::FormatQuery(CTLQuery* query, PetriEngine::PetriNet *net){
1214+ query = FillAtom(query,net);
1215+ query = ConvertAG(query);
1216+ query = ConvertEG(query);
1217+ IdSetting(query, 0);
1218+ query = TemporalSetting(query);
1219+ //assert(false);
1220+ return query;
1221+}
1222+
1223+CTLQuery* CTLParser_v2::TemporalSetting(CTLQuery* query) {
1224+ CTLType query_type = query->GetQueryType();
1225+ if(query_type == EVAL){
1226+ assert(!query->IsTemporal);
1227+ return query;
1228+ }
1229+ else if (query_type == LOPERATOR){
1230+ Quantifier quan = query->GetQuantifier();
1231+ if(quan != NEG){
1232+ query->SetFirstChild(TemporalSetting(query->GetFirstChild()));
1233+ query->SetSecondChild(TemporalSetting(query->GetSecondChild()));
1234+ query->IsTemporal = (query->GetFirstChild()->IsTemporal || query->GetSecondChild()->IsTemporal);
1235+ }
1236+ else{
1237+ query->SetFirstChild(TemporalSetting(query->GetFirstChild()));
1238+ query->IsTemporal = (query->GetFirstChild()->IsTemporal);
1239+ }
1240+ return query;
1241+ }
1242+ else if (query_type == PATHQEURY){
1243+ assert(query->IsTemporal);
1244+ if (query->GetPath() == U){
1245+ query->SetFirstChild(TemporalSetting(query->GetFirstChild()));
1246+ query->SetSecondChild(TemporalSetting(query->GetSecondChild()));
1247+ }
1248+ else{
1249+ query->SetFirstChild(TemporalSetting(query->GetFirstChild()));
1250+ }
1251+ return query;
1252+ } else {
1253+ //this should not happen
1254+ assert(false);
1255+ }
1256+}
1257+
1258+//returns next available id
1259+int CTLParser_v2::IdSetting(CTLQuery *query, int id)
1260+{
1261+ query->Id = id;
1262+ CTLType query_type = query->GetQueryType();
1263+ if(query_type == EVAL){
1264+ assert(!query->IsTemporal);
1265+ query->Depth = 0;
1266+ return id + 1;
1267+ }
1268+ else if (query_type == LOPERATOR){
1269+ Quantifier quan = query->GetQuantifier();
1270+ if(quan != NEG){
1271+ int afterFirst = IdSetting(query->GetFirstChild(), id + 1);
1272+ int afterSecond = IdSetting(query->GetSecondChild(), afterFirst);
1273+ query->Depth = std::max(query->GetFirstChild()->Depth, query->GetSecondChild()->Depth) + 1;
1274+ return afterSecond;
1275+ }
1276+ else{
1277+ int afterFirst = IdSetting(query->GetFirstChild(), id + 1);
1278+ query->Depth = query->GetFirstChild()->Depth + 1;
1279+ return afterFirst;
1280+ }
1281+ }
1282+ else if (query_type == PATHQEURY){
1283+ assert(query->IsTemporal);
1284+ if (query->GetPath() == U){
1285+ int afterFirst = IdSetting(query->GetFirstChild(), id + 1);
1286+ int afterSecond = IdSetting(query->GetSecondChild(), afterFirst);
1287+ query->Depth = std::max(query->GetFirstChild()->Depth, query->GetSecondChild()->Depth) + 1;
1288+ return afterSecond;
1289+ }
1290+ else{
1291+ int afterFirst = IdSetting(query->GetFirstChild(), id + 1);
1292+ query->Depth = query->GetFirstChild()->Depth + 1;
1293+ return afterFirst;
1294+ }
1295+ } else {
1296+ //this should not happen
1297+ assert(false);
1298+ }
1299+}
1300+
1301+
1302+CTLQuery* CTLParser_v2::FillAtom(CTLQuery* query, PetriEngine::PetriNet *net) {
1303+ CTLType query_type = query->GetQueryType();
1304+ if(query_type == EVAL){
1305+ EvaluateableProposition *proposition = new EvaluateableProposition(query->GetAtom(), net);
1306+ query->SetProposition(proposition);
1307+ return query;
1308+ }
1309+ else if (query_type == LOPERATOR){
1310+ Quantifier quan = query->GetQuantifier();
1311+ if(quan != NEG){
1312+ FillAtom(query->GetFirstChild(),net);
1313+ FillAtom(query->GetSecondChild(),net);
1314+ }
1315+ else{
1316+ FillAtom(query->GetFirstChild(),net);
1317+ }
1318+ return query;
1319+ }
1320+ else if (query_type == PATHQEURY){
1321+ if (query->GetPath() == U){
1322+ FillAtom(query->GetFirstChild(),net);
1323+ FillAtom(query->GetSecondChild(),net);
1324+ }
1325+ else{
1326+ FillAtom(query->GetFirstChild(),net);
1327+ }
1328+ return query;
1329+ }
1330+ else assert(false && "Could not traverse unknown query type");
1331+}
1332+
1333+CTLQuery* CTLParser_v2::ConvertAG(CTLQuery* query) {
1334+ CTLType query_type = query->GetQueryType();
1335+ if(query_type == EVAL){
1336+ return query;
1337+ }
1338+ else if (query_type == LOPERATOR){
1339+ Quantifier quan = query->GetQuantifier();
1340+ if(quan != NEG){
1341+ query->SetFirstChild(ConvertAG(query->GetFirstChild()));
1342+ query->SetSecondChild(ConvertAG(query->GetSecondChild()));
1343+ }
1344+ else{
1345+ query->SetFirstChild(ConvertAG(query->GetFirstChild()));
1346+ }
1347+ return query;
1348+ }
1349+ else if (query_type == PATHQEURY){
1350+ if (query->GetPath() == U){
1351+ query->SetFirstChild(ConvertAG(query->GetFirstChild()));
1352+ query->SetSecondChild(ConvertAG(query->GetSecondChild()));
1353+ }
1354+ else if (query->GetQuantifier() == A && query->GetPath() == G){
1355+
1356+ CTLQuery *neg_two = new CTLQuery(NEG, pError, false, "");
1357+ neg_two->SetFirstChild(query->GetFirstChild());
1358+ CTLQuery *ef_q = new CTLQuery(E, F, false, "");
1359+ ef_q->SetFirstChild(neg_two);
1360+ CTLQuery *neg_one = new CTLQuery(NEG, pError, false, "");
1361+ neg_one->SetFirstChild(ef_q);
1362+ query = neg_one;
1363+
1364+ query->SetFirstChild(ConvertAG(query->GetFirstChild()));
1365+ }
1366+ else{
1367+ query->SetFirstChild(ConvertAG(query->GetFirstChild()));
1368+ }
1369+ return query;
1370+ }
1371+ else assert(false && "Could not traverse unknown query type");
1372+}
1373+
1374+CTLQuery* CTLParser_v2::ConvertEG(CTLQuery* query) {
1375+ CTLType query_type = query->GetQueryType();
1376+ if(query_type == EVAL){
1377+ return query;
1378+ }
1379+ else if (query_type == LOPERATOR){
1380+ Quantifier quan = query->GetQuantifier();
1381+ if(quan != NEG){
1382+ query->SetFirstChild(ConvertEG(query->GetFirstChild()));
1383+ query->SetSecondChild(ConvertEG(query->GetSecondChild()));
1384+ }
1385+ else{
1386+ query->SetFirstChild(ConvertEG(query->GetFirstChild()));
1387+ }
1388+ return query;
1389+ }
1390+ else if (query_type == PATHQEURY){
1391+ if (query->GetPath() == U){
1392+ query->SetFirstChild(ConvertEG(query->GetFirstChild()));
1393+ query->SetSecondChild(ConvertEG(query->GetSecondChild()));
1394+ }
1395+ else if (query->GetQuantifier() == E && query->GetPath() == G){
1396+
1397+ CTLQuery *neg_two = new CTLQuery(NEG, pError, false, "");
1398+ neg_two->SetFirstChild(query->GetFirstChild());
1399+ CTLQuery *ef_q = new CTLQuery(A, F, false, "");
1400+ ef_q->SetFirstChild(neg_two);
1401+ CTLQuery *neg_one = new CTLQuery(NEG, pError, false, "");
1402+ neg_one->SetFirstChild(ef_q);
1403+ query = neg_one;
1404+
1405+ query->SetFirstChild(ConvertEG(query->GetFirstChild()));
1406+ }
1407+ else{
1408+ query->SetFirstChild(ConvertEG(query->GetFirstChild()));
1409+ }
1410+ return query;
1411+ }
1412+ else assert(false && "Could not traverse unknown query type");
1413+}
1414+
1415+
1416+CTLQuery * CTLParser_v2::ParseXMLQuery(std::vector<char> buffer, int query_number) {
1417+ #ifdef DEBUG
1418+ std::cout << "Creating doc\n" << std::flush;
1419+ #endif
1420+ xml_document<> doc;
1421+ xml_node<> * root_node;
1422+
1423+ #ifdef DEBUG
1424+ std::cout << "Size of Path enum: " << sizeof(Path)*8 <<"\n";
1425+ #endif
1426+ doc.parse<0>(&buffer[0]);
1427+
1428+
1429+#ifdef DEBUG
1430+ std::cout << "First node id: " << doc.first_node()->name() << std::endl;
1431+#endif
1432+
1433+ root_node = doc.first_node();
1434+
1435+#ifdef Analysis
1436+ std::cout << "\nAnalysis:: Queries:" << std::endl;
1437+#endif
1438+ int i = 1;
1439+ for (xml_node<> * property_node = root_node->first_node("property"); property_node; property_node = property_node->next_sibling()) {
1440+ if(i == query_number){
1441+ xml_node<> * id_node = property_node->first_node("id");
1442+ xml_node<> * formula_node = id_node->next_sibling("description")->next_sibling("formula");
1443+ CTLQuery * query = xmlToCTLquery(formula_node->first_node());
1444+ return query;
1445+ }
1446+ i++;
1447+ }
1448+ assert(false && "Query number did not match a property in the provided .xml file.");
1449+}
1450+
1451+QueryMeta* CTLParser_v2::GetQueryMetaData(std::vector<char> buffer) {
1452+ xml_document<> doc;
1453+ xml_node<> * root_node;
1454+ doc.parse<0>(&buffer[0]);
1455+ root_node = doc.first_node();
1456+ QueryMeta *meta_d = new QueryMeta();
1457+ xml_node<> * first_property_node = root_node->first_node("property");
1458+ xml_node<> * id_node = first_property_node->first_node("id");
1459+ std::string model_name(id_node->value());
1460+ int i = 0;
1461+ for (xml_node<> * property_node = root_node->first_node("property"); property_node; property_node = property_node->next_sibling()) {
1462+ i++;
1463+ }
1464+ meta_d->numberof_queries = i;
1465+ std::size_t pos = model_name.find_last_of("-0") - 1;
1466+ meta_d->model_name = model_name.substr(0, pos);
1467+ return meta_d;
1468+}
1469+
1470+
1471+CTLQuery* CTLParser_v2::xmlToCTLquery(xml_node<> * root) {
1472+ char *root_name = root->name();
1473+ char firstLetter = root_name[0];
1474+ CTLQuery *query;
1475+ if (firstLetter == 'a') {
1476+ //Construct all-paths
1477+ query = new CTLQuery(A, getPathOperator(root), false, "");
1478+ assert(query->GetQuantifier() == A && "Failed setting quantifier");
1479+ }
1480+ else if (firstLetter == 'e' ) {
1481+ //Construct exists-path
1482+ query = new CTLQuery(E, getPathOperator(root), false, "");
1483+ assert(query->GetQuantifier() == E && "Failed setting path operator");
1484+ }
1485+ else if (firstLetter == 'n' ) {
1486+ //Construct negation
1487+ query = new CTLQuery(NEG, pError, false, "");
1488+ assert(query->GetQuantifier() == NEG && "Failed setting negation operator");
1489+ }
1490+ else if (firstLetter == 'c' ) {
1491+ //Construct conjunction
1492+ query = new CTLQuery(AND, pError, false, "");
1493+ assert(query->GetQuantifier() == AND && "Failed setting and operator");
1494+ }
1495+ else if (firstLetter == 'd' ) {
1496+ //Construct disjunction
1497+ query = new CTLQuery(OR, pError, false, "");
1498+ assert(query->GetQuantifier() == OR && "Failed setting or operator");
1499+ }
1500+ else if (firstLetter == 'i' ) {
1501+ //Construct Atom
1502+ std::string atom_str = "";
1503+ if (root_name[1] == 's' ){
1504+ //Fireability Query File
1505+ atom_str = root->name();
1506+ atom_str = atom_str + "(";
1507+ root = root->first_node();
1508+ atom_str = atom_str + root->value();
1509+ for (xml_node<> * transition_node = root->next_sibling(); transition_node; transition_node = transition_node->next_sibling()) {
1510+ atom_str = atom_str + ", " + transition_node->value();
1511+ }
1512+ atom_str = atom_str + ")";
1513+ }
1514+ else if (root_name[1] == 'n') {
1515+ //Cardinality Query File
1516+ std::string loperator = root->name();
1517+ xml_node<> * par_node = root->first_node();
1518+ std::string first = parsePar(par_node);
1519+ par_node = par_node->next_sibling();
1520+ std::string second = parsePar(par_node);
1521+
1522+ loperator = loperator_sym(loperator);
1523+
1524+ atom_str = first + loperator + second;
1525+
1526+ }
1527+ else assert(false && "Incorrectly format of .xml file provided");
1528+ query = new CTLQuery(EMPTY, pError, true, atom_str);
1529+ query->Depth = 0;
1530+ return query;
1531+ }
1532+ else if (firstLetter == 't' ){
1533+ std::string atom_str = "integer-constant(0) le integer-constant(0)";
1534+ query = new CTLQuery(EMPTY, pError, true, atom_str);
1535+ query->Depth = 0;
1536+ return query;
1537+ }
1538+ else if (firstLetter == 'f' ){
1539+ std::string atom_str = "integer-constant(2) le integer-constant(0)";
1540+ query = new CTLQuery(EMPTY, pError, true, atom_str);
1541+ query->Depth = 0;
1542+ return query;
1543+ }
1544+ else assert(false && "Failed parsing .xml file provided. Incorrect format.");
1545+
1546+ if (query->GetPath() == U) {
1547+ xml_node<> * child_node = root->first_node()->first_node();
1548+ query->SetFirstChild(xmlToCTLquery(child_node->first_node()));
1549+ child_node = child_node->next_sibling();
1550+ query->SetSecondChild(xmlToCTLquery(child_node->first_node()));
1551+
1552+ query->Depth = (max_depth(query->GetFirstChild()->Depth, query->GetSecondChild()->Depth)) + 1;
1553+ }
1554+ else if (query->GetQuantifier() == AND || query->GetQuantifier() == OR) {
1555+ xml_node<> * child_node = root->first_node();
1556+ query->SetFirstChild(xmlToCTLquery(child_node));
1557+ child_node = child_node->next_sibling();
1558+ query->SetSecondChild(xmlToCTLquery(child_node));
1559+
1560+ query->Depth = (max_depth(query->GetFirstChild()->Depth, query->GetSecondChild()->Depth)) + 1;
1561+ }
1562+ else if (query->GetQuantifier() == NEG) {
1563+ query->SetFirstChild(xmlToCTLquery(root->first_node()));
1564+ query->Depth = query->GetFirstChild()->Depth + 1;
1565+ }
1566+ else if (query->GetPath() == pError){
1567+ assert(false && "Failed setting Path operator");
1568+ }
1569+ else if (query->GetQueryType() == PATHQEURY) {
1570+ query->SetFirstChild(xmlToCTLquery(root->first_node()->first_node()));
1571+ query->Depth = query->GetFirstChild()->Depth + 1;
1572+ }
1573+ else{
1574+ assert(false && "Attemting to give atom children - ERROR");
1575+ }
1576+
1577+ return query;
1578+}
1579+
1580+Path CTLParser_v2::getPathOperator(xml_node<> * quantifyer_node){
1581+ char path_firstLetter = quantifyer_node->first_node()->name()[0];
1582+ if(path_firstLetter == 'f')
1583+ return F;
1584+ else if (path_firstLetter == 'g')
1585+ return G;
1586+ else if (path_firstLetter == 'n')
1587+ return X;
1588+ else if (path_firstLetter == 'u')
1589+ return U;
1590+ else assert(false && "Failed parsing path operator. Incorrect format.");
1591+}
1592+
1593+std::string CTLParser_v2::parsePar(xml_node<> * parameter){
1594+ std::string parameter_str = parameter->name();
1595+ parameter_str = parameter_str + "(";
1596+
1597+ if (parameter->name()[0] == 't'){
1598+ xml_node<> * place_node = parameter->first_node();
1599+ parameter_str = parameter_str + place_node->value();
1600+ for(place_node = place_node->next_sibling(); place_node; place_node = place_node->next_sibling()){
1601+ parameter_str = parameter_str + ", " + place_node->value();
1602+ }
1603+ parameter_str = parameter_str + ")";
1604+ }
1605+
1606+ else if(parameter->name()[0] == 'i'){
1607+ parameter_str = parameter_str + parameter->value() + ")";
1608+ }
1609+ else assert(false && "Failed parsing cardinality parameter. Incorrect format.");
1610+ return parameter_str;
1611+}
1612+
1613+/*
1614+ for (xml_node<> * transition_node = root->next_sibling(); transition_node; transition_node = transition_node->next_sibling()) {
1615+ atom_str = atom_str + ", " + transition_node->value();
1616+ }
1617+ atom_str = atom_str + ")";
1618+ */
1619+
1620+int CTLParser_v2::max_depth(int a, int b){
1621+ if(a < b) return b; return a;
1622+}
1623+
1624+std::string CTLParser_v2::loperator_sym(std::string loperator){
1625+ if(loperator.compare("integer-le") == 0){
1626+ return " le ";
1627+ }
1628+ else if(loperator.compare("integer-ge")){
1629+ return " ge ";
1630+ }
1631+ else if(loperator.compare("integer-eq")){
1632+ return " eq ";
1633+ }
1634+ else return " " + loperator + " ";
1635+}
1636+
1637+CTLQuery * CTLParser_v2::CopyQuery(CTLQuery *source){
1638+ if(source->GetQueryType() == EVAL){
1639+ return new CTLQuery(EMPTY, pError, true, source->GetAtom());
1640+ }
1641+ else if(source->GetQueryType() == LOPERATOR){
1642+ CTLQuery *dest = new CTLQuery(source->GetQuantifier(), pError, false, "");
1643+ if(source->GetQuantifier() != NEG){
1644+ dest->SetFirstChild(CopyQuery(source->GetFirstChild()));
1645+ dest->SetSecondChild(CopyQuery(source->GetSecondChild()));
1646+ }
1647+ else {
1648+ dest->SetFirstChild(CopyQuery(source->GetFirstChild()));
1649+ }
1650+ return dest;
1651+ }
1652+ else if(source->GetQueryType() == PATHQEURY){
1653+ CTLQuery *dest = new CTLQuery(source->GetQuantifier(), source->GetPath(), false, "");
1654+ if(source->GetPath() == U){
1655+ dest->SetFirstChild(CopyQuery(source->GetFirstChild()));
1656+ dest->SetSecondChild(CopyQuery(source->GetSecondChild()));
1657+ }
1658+ else{
1659+ dest->SetFirstChild(CopyQuery(source->GetFirstChild()));
1660+ }
1661+ return dest;
1662+ }
1663+ else assert(false && "ERROR::: Copying query failed");
1664+}
1665
1666=== added file 'CTLParser/CTLParser_v2.h'
1667--- CTLParser/CTLParser_v2.h 1970-01-01 00:00:00 +0000
1668+++ CTLParser/CTLParser_v2.h 2016-05-20 07:41:18 +0000
1669@@ -0,0 +1,56 @@
1670+/*
1671+ * To change this license header, choose License Headers in Project Properties.
1672+ * To change this template file, choose Tools | Templates
1673+ * and open the template in the editor.
1674+ */
1675+
1676+/*
1677+ * File: CTLParser_v2.h
1678+ * Author: mossns
1679+ *
1680+ * Created on April 22, 2016, 10:15 AM
1681+ */
1682+
1683+#ifndef CTLPARSER_V2_H
1684+#define CTLPARSER_V2_H
1685+
1686+#include "rapidxml-1.13/rapidxml.hpp"
1687+#include <vector>
1688+#include <string>
1689+#include <stdio.h>
1690+#include "CTLQuery.h"
1691+
1692+struct QueryMeta{
1693+ int numberof_queries = 0;
1694+ std::string model_name;
1695+
1696+};
1697+
1698+class CTLParser_v2 {
1699+public:
1700+ CTLParser_v2();
1701+ CTLParser_v2(const CTLParser_v2& orig);
1702+ virtual ~CTLParser_v2();
1703+ CTLQuery * ParseXMLQuery(std::vector<char> buffer, int query_number);
1704+ CTLQuery* FormatQuery(CTLQuery* query, PetriEngine::PetriNet *net);
1705+ std::string QueryToString(CTLQuery* query);
1706+ QueryMeta * GetQueryMetaData(std::vector<char> buffer);
1707+private:
1708+ CTLQuery* xmlToCTLquery(rapidxml::xml_node<> * root);
1709+ std::string parsePar(rapidxml::xml_node<> * parameter);
1710+ Path getPathOperator(rapidxml::xml_node<> * quantifyer_node);
1711+ int max_depth(int a, int b);
1712+ std::string loperator_sym(std::string loperator);
1713+ CTLQuery * CopyQuery(CTLQuery *source);
1714+
1715+ CTLQuery* FillAtom(CTLQuery* query, PetriEngine::PetriNet *net);
1716+ CTLQuery* ConvertAG(CTLQuery* query);
1717+ CTLQuery* ConvertEG(CTLQuery* query);
1718+ CTLQuery* TemporalSetting(CTLQuery* query);
1719+ int IdSetting(CTLQuery* query, int id);
1720+ QueryMeta *_meta;
1721+
1722+};
1723+
1724+#endif /* CTLPARSER_V2_H */
1725+
1726
1727=== added file 'CTLParser/CTLQuery.cpp'
1728--- CTLParser/CTLQuery.cpp 1970-01-01 00:00:00 +0000
1729+++ CTLParser/CTLQuery.cpp 2016-05-20 07:41:18 +0000
1730@@ -0,0 +1,159 @@
1731+/*
1732+ * To change this license header, choose License Headers in Project Properties.
1733+ * To change this template file, choose Tools | Templates
1734+ * and open the template in the editor.
1735+ */
1736+
1737+/*
1738+ * File: CTLQuery.cpp
1739+ * Author: mossns
1740+ *
1741+ * Created on April 22, 2016, 7:57 AM
1742+ */
1743+
1744+#include <string.h>
1745+
1746+#include "CTLQuery.h"
1747+#include "CTLParser.h"
1748+
1749+CTLQuery::CTLQuery(Quantifier q, Path p, bool isAtom, std::string atom_str) {
1750+ if(isAtom){
1751+ assert(q == EMPTY);
1752+ assert(p == pError);
1753+ assert(atom_str.compare("") != 0);
1754+
1755+ _hasAtom = true;
1756+ _hasQuantifier = false;
1757+ _hasPath = false;
1758+ _q = q;
1759+ _path = p;
1760+ _a = atom_str;
1761+ IsTemporal = false;
1762+ }
1763+ else if(q == AND || q == OR || q == NEG){
1764+ assert(p == pError);
1765+ _hasAtom = false;
1766+ _hasQuantifier = true;
1767+ _hasPath = false;
1768+ _q = q;
1769+ _path = p;
1770+ _a = "";
1771+ IsTemporal = false;
1772+ }
1773+ else{
1774+ assert(q != EMPTY);
1775+ assert(p != pError);
1776+ _hasAtom = false;
1777+ _hasQuantifier = true;
1778+ _hasPath = true;
1779+ _q = q;
1780+ _path = p;
1781+ _a = "";
1782+ IsTemporal = true;
1783+ }
1784+
1785+}
1786+
1787+CTLQuery::~CTLQuery() {
1788+}
1789+
1790+CTLType CTLQuery::GetQueryType(){
1791+ if(_hasAtom)
1792+ return EVAL;
1793+ else if(_path != pError)
1794+ return PATHQEURY;
1795+ else if(_q == AND || _q == OR || _q == NEG)
1796+ return LOPERATOR;
1797+ return TYPE_ERROR;
1798+}
1799+
1800+CTLQuery* CTLQuery::GetFirstChild(){
1801+ if(_hasAtom){
1802+ std::cout<<"Query " << ToString() << " does not have child"<<std::endl;
1803+ throw 20;
1804+ }
1805+ return _firstchild;
1806+}
1807+
1808+CTLQuery* CTLQuery::GetSecondChild(){
1809+ assert(!_hasAtom && "Query does not have children");
1810+ assert(!(_path == F || _path == G || _path == X) && "Query does not have second child");
1811+ assert(!(_q == NEG) && "Query does not have second child");
1812+ return _secondchild;
1813+}
1814+
1815+void CTLQuery::SetFirstChild(CTLQuery *q){
1816+ _firstchild = q;
1817+}
1818+
1819+void CTLQuery::SetSecondChild(CTLQuery *q){
1820+ _secondchild = q;
1821+}
1822+
1823+Quantifier CTLQuery::GetQuantifier(){
1824+ return _q;
1825+}
1826+
1827+Path CTLQuery::GetPath(){
1828+ return _path;
1829+}
1830+
1831+std::string CTLQuery::GetAtom(){
1832+ return _a;
1833+}
1834+
1835+EvaluateableProposition* CTLQuery::GetProposition(){
1836+ assert(_hasAtom && "Query does not have proposition");
1837+ return _proposition;
1838+}
1839+
1840+void CTLQuery::SetProposition(EvaluateableProposition *p){
1841+ assert(_hasAtom && "Query does not have proposition");
1842+ _proposition = p;
1843+}
1844+
1845+std::string CTLQuery::ToString(){
1846+ if(_hasAtom){
1847+ return _a;
1848+ }
1849+ else if(_q == AND){
1850+ return " & ";
1851+ }
1852+ else if(_q == OR){
1853+ return " | ";
1854+ }
1855+ else if(_q == NEG){
1856+ return "!";
1857+ }
1858+ else if(_q == A || _q == E){
1859+ std::string quanti = "";
1860+ if (_q == A){
1861+ quanti = "A";
1862+ }
1863+ else quanti = "E";
1864+ if(_path == F){
1865+ return quanti + "F";
1866+ }
1867+ else if(_path == G){
1868+ return quanti + "G";
1869+ }
1870+ else if(_path == X){
1871+ return quanti + "X";
1872+ }
1873+ else if(_path == U){
1874+
1875+ return quanti.append("U");
1876+ }
1877+ else{
1878+ std::cout<<"::::::Error Printing: Path was empty::::"<<std::endl;
1879+ assert(false);
1880+ }
1881+ }
1882+ else{
1883+ std::cout<<"::::::Error Printing: Q was empty::::"<<std::endl;
1884+ assert(false);
1885+ }
1886+}
1887+
1888+
1889+
1890
1891=== added file 'CTLParser/CTLQuery.h'
1892--- CTLParser/CTLQuery.h 1970-01-01 00:00:00 +0000
1893+++ CTLParser/CTLQuery.h 2016-05-20 07:41:18 +0000
1894@@ -0,0 +1,66 @@
1895+/*
1896+ * To change this license header, choose License Headers in Project Properties.
1897+ * To change this template file, choose Tools | Templates
1898+ * and open the template in the editor.
1899+ */
1900+
1901+/*
1902+ * File: CTLQuery.h
1903+ * Author: Søren Moss Nielsen
1904+ *
1905+ * Created on April 22, 2016, 7:57 AM
1906+ */
1907+
1908+#ifndef CTLQUERY_H
1909+#define CTLQUERY_H
1910+#include "CTLParser.h"
1911+#include "EvaluateableProposition.h"
1912+
1913+enum CTLType {PATHQEURY = 1, LOPERATOR = 2, EVAL = 3, TYPE_ERROR = -1};
1914+
1915+class CTLQuery {
1916+
1917+public:
1918+ CTLQuery(Quantifier q, Path p, bool isAtom, std::string atom_str);
1919+ virtual ~CTLQuery();
1920+
1921+ int Id;
1922+ int Depth;
1923+
1924+ CTLType GetQueryType();
1925+ CTLQuery* GetFirstChild();
1926+ CTLQuery* GetSecondChild();
1927+ void SetFirstChild(CTLQuery *q);
1928+ void SetSecondChild(CTLQuery *q);
1929+ std::string ToString();
1930+
1931+ Quantifier GetQuantifier();
1932+ Path GetPath();
1933+ std::string GetAtom();
1934+
1935+ EvaluateableProposition* GetProposition();
1936+ void SetProposition(EvaluateableProposition *p);
1937+
1938+ bool IsTemporal;
1939+
1940+
1941+private:
1942+ std::string CreateEvaluateableProposition(std::string a);
1943+
1944+ bool _hasQuantifier;
1945+ bool _hasPath;
1946+ bool _hasAtom;
1947+ Quantifier _q;
1948+ Path _path;
1949+ std::string _a;
1950+
1951+ CTLQuery* _firstchild;
1952+ CTLQuery* _secondchild;
1953+
1954+ EvaluateableProposition* _proposition;
1955+
1956+
1957+};
1958+
1959+#endif /* CTLQUERY_H */
1960+
1961
1962=== added file 'CTLParser/EvaluateableProposition.cpp'
1963--- CTLParser/EvaluateableProposition.cpp 1970-01-01 00:00:00 +0000
1964+++ CTLParser/EvaluateableProposition.cpp 2016-05-20 07:41:18 +0000
1965@@ -0,0 +1,189 @@
1966+/*
1967+ * To change this license header, choose License Headers in Project Properties.
1968+ * To change this template file, choose Tools | Templates
1969+ * and open the template in the editor.
1970+ */
1971+
1972+/*
1973+ * File: EvaluateableProposition.cpp
1974+ * Author: mossns
1975+ *
1976+ * Created on April 27, 2016, 2:36 PM
1977+ */
1978+
1979+#include <string>
1980+#include <stdexcept>
1981+#include <sstream>
1982+
1983+#include "EvaluateableProposition.h"
1984+#include "CTLParser.h"
1985+
1986+namespace patch
1987+{
1988+ //A replacement for the standard to string function, which we cannot use because old OS X does not have c++11
1989+ template < typename T > std::string to_string( const T& n )
1990+ {
1991+ std::ostringstream stm ;
1992+ stm << n ;
1993+ return stm.str() ;
1994+ }
1995+}
1996+
1997+EvaluateableProposition::EvaluateableProposition(std::string a, PetriEngine::PetriNet *net) {
1998+ if(a.substr(0,2).compare("in") == 0 || a.substr(0,2).compare("to") == 0){
1999+ _type = CARDINALITY;
2000+ _loperator = SetLoperator(a);
2001+ assert(_loperator != NOT_CARDINALITY);
2002+
2003+ size_t begin = a.find('(') + 1;
2004+ size_t end = a.find(')') - begin;
2005+ std::string first_parameter_str = a.substr(begin, end);
2006+ a = a.substr(a.find(')') + 1);
2007+
2008+ begin = a.find('(') + 1;
2009+ end = a.find(')') - begin;
2010+ std::string second_parameter_str = a.substr(begin, end);
2011+ _firstParameter = CreateParameter(first_parameter_str, net->placeNames(), net->numberOfPlaces());
2012+ _secondParameter = CreateParameter(second_parameter_str, net->placeNames(), net->numberOfPlaces());
2013+ }
2014+ else if(a.substr(0,2).compare("is") == 0){
2015+ _type = FIREABILITY;
2016+ _loperator = NOT_CARDINALITY;
2017+ size_t s_pos = a.find('(') + 1;
2018+ size_t e_pos = a.find(')') - 1;
2019+ assert(s_pos < e_pos);
2020+ int fire_str_length = e_pos - s_pos + 1;
2021+ std::string fireset_str = a.substr(s_pos, fire_str_length);
2022+ SetFireset(fireset_str, net->transitionNames(), net->numberOfTransitions());
2023+ }
2024+ else if(a.substr(0,2).compare("tr") == 0){
2025+
2026+ }
2027+ else if(a.substr(0,2).compare("fa") == 0){
2028+
2029+ }
2030+ else{
2031+ assert(false && "Atomic string proposed for proposition could not be parsed");
2032+ }
2033+}
2034+
2035+EvaluateableProposition::~EvaluateableProposition() {
2036+}
2037+
2038+PropositionType EvaluateableProposition::GetPropositionType(){
2039+ return _type;
2040+}
2041+
2042+LoperatorType EvaluateableProposition::GetLoperator(){
2043+ assert(_type == CARDINALITY && "Proposition is not a cardinality proposition");
2044+ return _loperator;
2045+}
2046+
2047+std::vector<int> EvaluateableProposition::GetFireset() {
2048+ assert(_type == FIREABILITY && "Proposition is not a fireability proposition");
2049+ return _fireset;
2050+}
2051+
2052+void EvaluateableProposition::SetFireset(std::string fireset_str, std::vector<std::string> t_names, unsigned int numberof_t){
2053+ std::string restof_firestring = fireset_str;
2054+ while(restof_firestring.length() > 0){
2055+ size_t position = restof_firestring.find(',');
2056+ std::string current_t = restof_firestring.substr(0, position);
2057+ for(int i = 0; i < numberof_t; i++){
2058+ if (current_t.compare(t_names[i]) == 0){
2059+ _fireset.push_back(i);
2060+ }
2061+ }
2062+ if (position != -1)
2063+ restof_firestring = restof_firestring.substr(position);
2064+ else
2065+ restof_firestring = "";
2066+ }
2067+ for ( auto f : _fireset){
2068+ std::cout<<f<<" is id of "<< t_names[f]<<std::endl;
2069+ }
2070+}
2071+
2072+CardinalityParameter* EvaluateableProposition::CreateParameter(std::string parameter_str, std::vector<std::string> p_names, unsigned int numberof_p){
2073+ CardinalityParameter *param = new CardinalityParameter();
2074+ std::string::size_type sz;
2075+ char c;
2076+ if(sscanf(parameter_str.c_str(), "%d%c", &param->value, &c) == 1) {
2077+ //If string is identifier starting with a number, you will read two items.
2078+ //If it's an identifier starting with a character, you will read zero items.
2079+ //The only time when you read just one item if the whole string is just numbers.
2080+ param->isPlace = false;
2081+ } else { //error
2082+
2083+ param->isPlace = true;
2084+ std::vector<std::string> places_str;
2085+ std::size_t found = parameter_str.find(",");
2086+
2087+ while(found != parameter_str.npos){
2088+ std::string temp = parameter_str.substr(0, found);
2089+ places_str.push_back(temp);
2090+ parameter_str = parameter_str.substr(found + 2);
2091+ found = parameter_str.find(",");
2092+ }
2093+
2094+ places_str.push_back(parameter_str);
2095+
2096+ for(int i = 0; i < numberof_p; i++){
2097+ for(std::string place : places_str){
2098+ if(p_names[i].compare(place) == 0){
2099+ param->places_i.push_back(i);
2100+ }
2101+ }
2102+ }
2103+ }
2104+ return param;
2105+}
2106+
2107+LoperatorType EvaluateableProposition::SetLoperator(std::string atom_str){
2108+ std::string loperator_str = atom_str.substr(atom_str.find(')'));
2109+ loperator_str = loperator_str.substr(0, loperator_str.find('('));
2110+ if(loperator_str.compare(" le "))
2111+ return LEQ;
2112+ else if (loperator_str.compare(" ge "))
2113+ return GRQ;
2114+ else if (loperator_str.compare(" eq "))
2115+ return EQ;
2116+ else assert(false && "Could not parse the given logical operator");
2117+}
2118+
2119+std::string EvaluateableProposition::ToString() {
2120+ if (_type == FIREABILITY) {
2121+ std::string fire_str = "Fireset(";
2122+ for(auto f : _fireset){
2123+ fire_str = fire_str + " " + patch::to_string(f);
2124+ }
2125+ return fire_str + ")";
2126+ }
2127+ else if (_type == CARDINALITY){
2128+ std::string cardi_str = "(";
2129+ if(_firstParameter->isPlace)
2130+ cardi_str = cardi_str + "place(" + patch::to_string(_firstParameter->value) + ")";
2131+ else
2132+ cardi_str = cardi_str = patch::to_string(_firstParameter->value);
2133+
2134+ cardi_str = cardi_str + " le ";
2135+
2136+ if(_secondParameter->isPlace)
2137+ cardi_str = cardi_str + "place(" + patch::to_string(_secondParameter->value) + ")";
2138+ else
2139+ cardi_str = cardi_str = patch::to_string(_secondParameter->value);
2140+ return cardi_str + ")";
2141+ }
2142+ else
2143+ assert(false && "Proposition had no type");
2144+}
2145+
2146+CardinalityParameter* EvaluateableProposition::GetFirstParameter() {
2147+ assert(_type == CARDINALITY);
2148+ return _firstParameter;
2149+}
2150+
2151+CardinalityParameter* EvaluateableProposition::GetSecondParameter() {
2152+ assert(_type == CARDINALITY);
2153+ return _secondParameter;
2154+}
2155
2156=== added file 'CTLParser/EvaluateableProposition.h'
2157--- CTLParser/EvaluateableProposition.h 1970-01-01 00:00:00 +0000
2158+++ CTLParser/EvaluateableProposition.h 2016-05-20 07:41:18 +0000
2159@@ -0,0 +1,53 @@
2160+/*
2161+ * To change this license header, choose License Headers in Project Properties.
2162+ * To change this template file, choose Tools | Templates
2163+ * and open the template in the editor.
2164+ */
2165+
2166+/*
2167+ * File: EvaluateableProposition.h
2168+ * Author: mossns
2169+ *
2170+ * Created on April 27, 2016, 2:36 PM
2171+ */
2172+
2173+#ifndef EVALUATEABLEPROPOSITION_H
2174+#define EVALUATEABLEPROPOSITION_H
2175+#include <vector>
2176+#include "PetriEngine/PetriNet.h"
2177+
2178+
2179+enum PropositionType {CARDINALITY = 0, FIREABILITY = 1};
2180+enum LoperatorType {NOT_CARDINALITY = -1, EQ = 0, LE = 1, LEQ = 2, GR = 3, GRQ = 4};
2181+
2182+struct CardinalityParameter{
2183+ bool isPlace;
2184+ int value;
2185+ std::vector<int> places_i;
2186+};
2187+
2188+class EvaluateableProposition {
2189+public:
2190+ EvaluateableProposition(std::string a, PetriEngine::PetriNet *net);
2191+ virtual ~EvaluateableProposition();
2192+ PropositionType GetPropositionType();
2193+ LoperatorType GetLoperator();
2194+ std::vector<int> GetFireset();
2195+ std::string ToString();
2196+ CardinalityParameter* GetFirstParameter();
2197+ CardinalityParameter* GetSecondParameter();
2198+private:
2199+ void SetFireset(std::string fireset_str, std::vector<std::string> t_names, unsigned int numberof_t);
2200+ CardinalityParameter* CreateParameter(std::string parameter_str, std::vector<std::string> p_names, unsigned int numberof_p);
2201+ LoperatorType SetLoperator(std::string atom_str);
2202+
2203+ PropositionType _type;
2204+ LoperatorType _loperator;
2205+ std::vector<int> _fireset;
2206+ CardinalityParameter* _firstParameter;
2207+ CardinalityParameter* _secondParameter;
2208+
2209+};
2210+
2211+#endif /* EVALUATEABLEPROPOSITION_H */
2212+
2213
2214=== added directory 'Tests/unitTesting'
2215=== added file 'Tests/unitTesting/catch.hpp'
2216--- Tests/unitTesting/catch.hpp 1970-01-01 00:00:00 +0000
2217+++ Tests/unitTesting/catch.hpp 2016-05-20 07:41:18 +0000
2218@@ -0,0 +1,10483 @@
2219+/*
2220+ * Catch v1.5.1
2221+ * Generated: 2016-04-28 08:12:37.387488
2222+ * ----------------------------------------------------------
2223+ * This file has been merged from multiple headers. Please don't edit it directly
2224+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
2225+ *
2226+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
2227+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2228+ */
2229+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
2230+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
2231+
2232+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
2233+
2234+#ifdef __clang__
2235+# pragma clang system_header
2236+#elif defined __GNUC__
2237+# pragma GCC system_header
2238+#endif
2239+
2240+// #included from: internal/catch_suppress_warnings.h
2241+
2242+#ifdef __clang__
2243+# ifdef __ICC // icpc defines the __clang__ macro
2244+# pragma warning(push)
2245+# pragma warning(disable: 161 1682)
2246+# else // __ICC
2247+# pragma clang diagnostic ignored "-Wglobal-constructors"
2248+# pragma clang diagnostic ignored "-Wvariadic-macros"
2249+# pragma clang diagnostic ignored "-Wc99-extensions"
2250+# pragma clang diagnostic ignored "-Wunused-variable"
2251+# pragma clang diagnostic push
2252+# pragma clang diagnostic ignored "-Wpadded"
2253+# pragma clang diagnostic ignored "-Wc++98-compat"
2254+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
2255+# pragma clang diagnostic ignored "-Wswitch-enum"
2256+# pragma clang diagnostic ignored "-Wcovered-switch-default"
2257+# endif
2258+#elif defined __GNUC__
2259+# pragma GCC diagnostic ignored "-Wvariadic-macros"
2260+# pragma GCC diagnostic ignored "-Wunused-variable"
2261+# pragma GCC diagnostic push
2262+# pragma GCC diagnostic ignored "-Wpadded"
2263+#endif
2264+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
2265+# define CATCH_IMPL
2266+#endif
2267+
2268+#ifdef CATCH_IMPL
2269+# ifndef CLARA_CONFIG_MAIN
2270+# define CLARA_CONFIG_MAIN_NOT_DEFINED
2271+# define CLARA_CONFIG_MAIN
2272+# endif
2273+#endif
2274+
2275+// #included from: internal/catch_notimplemented_exception.h
2276+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
2277+
2278+// #included from: catch_common.h
2279+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
2280+
2281+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
2282+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
2283+#ifdef CATCH_CONFIG_COUNTER
2284+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
2285+#else
2286+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
2287+#endif
2288+
2289+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
2290+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
2291+
2292+#include <sstream>
2293+#include <stdexcept>
2294+#include <algorithm>
2295+
2296+// #included from: catch_compiler_capabilities.h
2297+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
2298+
2299+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
2300+// The following features are defined:
2301+//
2302+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
2303+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
2304+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
2305+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
2306+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
2307+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
2308+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
2309+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
2310+
2311+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
2312+
2313+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
2314+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
2315+// ****************
2316+// Note to maintainers: if new toggles are added please document them
2317+// in configuration.md, too
2318+// ****************
2319+
2320+// In general each macro has a _NO_<feature name> form
2321+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
2322+// Many features, at point of detection, define an _INTERNAL_ macro, so they
2323+// can be combined, en-mass, with the _NO_ forms later.
2324+
2325+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
2326+
2327+#if defined(__cplusplus) && __cplusplus >= 201103L
2328+# define CATCH_CPP11_OR_GREATER
2329+#endif
2330+
2331+#ifdef __clang__
2332+
2333+# if __has_feature(cxx_nullptr)
2334+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
2335+# endif
2336+
2337+# if __has_feature(cxx_noexcept)
2338+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
2339+# endif
2340+
2341+# if defined(CATCH_CPP11_OR_GREATER)
2342+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
2343+# endif
2344+
2345+#endif // __clang__
2346+
2347+////////////////////////////////////////////////////////////////////////////////
2348+// Borland
2349+#ifdef __BORLANDC__
2350+
2351+#endif // __BORLANDC__
2352+
2353+////////////////////////////////////////////////////////////////////////////////
2354+// EDG
2355+#ifdef __EDG_VERSION__
2356+
2357+#endif // __EDG_VERSION__
2358+
2359+////////////////////////////////////////////////////////////////////////////////
2360+// Digital Mars
2361+#ifdef __DMC__
2362+
2363+#endif // __DMC__
2364+
2365+////////////////////////////////////////////////////////////////////////////////
2366+// GCC
2367+#ifdef __GNUC__
2368+
2369+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
2370+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
2371+# endif
2372+
2373+# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
2374+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
2375+# endif
2376+
2377+// - otherwise more recent versions define __cplusplus >= 201103L
2378+// and will get picked up below
2379+
2380+#endif // __GNUC__
2381+
2382+////////////////////////////////////////////////////////////////////////////////
2383+// Visual C++
2384+#ifdef _MSC_VER
2385+
2386+#if (_MSC_VER >= 1600)
2387+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
2388+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
2389+#endif
2390+
2391+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
2392+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
2393+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
2394+#endif
2395+
2396+#endif // _MSC_VER
2397+
2398+////////////////////////////////////////////////////////////////////////////////
2399+
2400+// Use variadic macros if the compiler supports them
2401+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
2402+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
2403+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
2404+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
2405+
2406+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
2407+
2408+#endif
2409+
2410+// Use __COUNTER__ if the compiler supports it
2411+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
2412+ ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
2413+ ( defined __clang__ && __clang_major__ >= 3 )
2414+
2415+#define CATCH_INTERNAL_CONFIG_COUNTER
2416+
2417+#endif
2418+
2419+////////////////////////////////////////////////////////////////////////////////
2420+// C++ language feature support
2421+
2422+// catch all support for C++11
2423+#if defined(CATCH_CPP11_OR_GREATER)
2424+
2425+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
2426+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
2427+# endif
2428+
2429+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
2430+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
2431+# endif
2432+
2433+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
2434+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
2435+# endif
2436+
2437+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
2438+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
2439+# endif
2440+
2441+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
2442+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
2443+# endif
2444+
2445+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
2446+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
2447+# endif
2448+
2449+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
2450+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
2451+# endif
2452+
2453+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
2454+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
2455+# endif
2456+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
2457+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
2458+# endif
2459+
2460+#endif // __cplusplus >= 201103L
2461+
2462+// Now set the actual defines based on the above + anything the user has configured
2463+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
2464+# define CATCH_CONFIG_CPP11_NULLPTR
2465+#endif
2466+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
2467+# define CATCH_CONFIG_CPP11_NOEXCEPT
2468+#endif
2469+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
2470+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
2471+#endif
2472+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
2473+# define CATCH_CONFIG_CPP11_IS_ENUM
2474+#endif
2475+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
2476+# define CATCH_CONFIG_CPP11_TUPLE
2477+#endif
2478+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
2479+# define CATCH_CONFIG_VARIADIC_MACROS
2480+#endif
2481+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
2482+# define CATCH_CONFIG_CPP11_LONG_LONG
2483+#endif
2484+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
2485+# define CATCH_CONFIG_CPP11_OVERRIDE
2486+#endif
2487+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
2488+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
2489+#endif
2490+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
2491+# define CATCH_CONFIG_COUNTER
2492+#endif
2493+
2494+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
2495+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
2496+#endif
2497+
2498+// noexcept support:
2499+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
2500+# define CATCH_NOEXCEPT noexcept
2501+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
2502+#else
2503+# define CATCH_NOEXCEPT throw()
2504+# define CATCH_NOEXCEPT_IS(x)
2505+#endif
2506+
2507+// nullptr support
2508+#ifdef CATCH_CONFIG_CPP11_NULLPTR
2509+# define CATCH_NULL nullptr
2510+#else
2511+# define CATCH_NULL NULL
2512+#endif
2513+
2514+// override support
2515+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
2516+# define CATCH_OVERRIDE override
2517+#else
2518+# define CATCH_OVERRIDE
2519+#endif
2520+
2521+// unique_ptr support
2522+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
2523+# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
2524+#else
2525+# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
2526+#endif
2527+
2528+namespace Catch {
2529+
2530+ struct IConfig;
2531+
2532+ struct CaseSensitive { enum Choice {
2533+ Yes,
2534+ No
2535+ }; };
2536+
2537+ class NonCopyable {
2538+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
2539+ NonCopyable( NonCopyable const& ) = delete;
2540+ NonCopyable( NonCopyable && ) = delete;
2541+ NonCopyable& operator = ( NonCopyable const& ) = delete;
2542+ NonCopyable& operator = ( NonCopyable && ) = delete;
2543+#else
2544+ NonCopyable( NonCopyable const& info );
2545+ NonCopyable& operator = ( NonCopyable const& );
2546+#endif
2547+
2548+ protected:
2549+ NonCopyable() {}
2550+ virtual ~NonCopyable();
2551+ };
2552+
2553+ class SafeBool {
2554+ public:
2555+ typedef void (SafeBool::*type)() const;
2556+
2557+ static type makeSafe( bool value ) {
2558+ return value ? &SafeBool::trueValue : 0;
2559+ }
2560+ private:
2561+ void trueValue() const {}
2562+ };
2563+
2564+ template<typename ContainerT>
2565+ inline void deleteAll( ContainerT& container ) {
2566+ typename ContainerT::const_iterator it = container.begin();
2567+ typename ContainerT::const_iterator itEnd = container.end();
2568+ for(; it != itEnd; ++it )
2569+ delete *it;
2570+ }
2571+ template<typename AssociativeContainerT>
2572+ inline void deleteAllValues( AssociativeContainerT& container ) {
2573+ typename AssociativeContainerT::const_iterator it = container.begin();
2574+ typename AssociativeContainerT::const_iterator itEnd = container.end();
2575+ for(; it != itEnd; ++it )
2576+ delete it->second;
2577+ }
2578+
2579+ bool startsWith( std::string const& s, std::string const& prefix );
2580+ bool endsWith( std::string const& s, std::string const& suffix );
2581+ bool contains( std::string const& s, std::string const& infix );
2582+ void toLowerInPlace( std::string& s );
2583+ std::string toLower( std::string const& s );
2584+ std::string trim( std::string const& str );
2585+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
2586+
2587+ struct pluralise {
2588+ pluralise( std::size_t count, std::string const& label );
2589+
2590+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
2591+
2592+ std::size_t m_count;
2593+ std::string m_label;
2594+ };
2595+
2596+ struct SourceLineInfo {
2597+
2598+ SourceLineInfo();
2599+ SourceLineInfo( char const* _file, std::size_t _line );
2600+ SourceLineInfo( SourceLineInfo const& other );
2601+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
2602+ SourceLineInfo( SourceLineInfo && ) = default;
2603+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
2604+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
2605+# endif
2606+ bool empty() const;
2607+ bool operator == ( SourceLineInfo const& other ) const;
2608+ bool operator < ( SourceLineInfo const& other ) const;
2609+
2610+ std::string file;
2611+ std::size_t line;
2612+ };
2613+
2614+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
2615+
2616+ // This is just here to avoid compiler warnings with macro constants and boolean literals
2617+ inline bool isTrue( bool value ){ return value; }
2618+ inline bool alwaysTrue() { return true; }
2619+ inline bool alwaysFalse() { return false; }
2620+
2621+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
2622+
2623+ void seedRng( IConfig const& config );
2624+ unsigned int rngSeed();
2625+
2626+ // Use this in variadic streaming macros to allow
2627+ // >> +StreamEndStop
2628+ // as well as
2629+ // >> stuff +StreamEndStop
2630+ struct StreamEndStop {
2631+ std::string operator+() {
2632+ return std::string();
2633+ }
2634+ };
2635+ template<typename T>
2636+ T const& operator + ( T const& value, StreamEndStop ) {
2637+ return value;
2638+ }
2639+}
2640+
2641+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
2642+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
2643+
2644+#include <ostream>
2645+
2646+namespace Catch {
2647+
2648+ class NotImplementedException : public std::exception
2649+ {
2650+ public:
2651+ NotImplementedException( SourceLineInfo const& lineInfo );
2652+ NotImplementedException( NotImplementedException const& ) {}
2653+
2654+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
2655+
2656+ virtual const char* what() const CATCH_NOEXCEPT;
2657+
2658+ private:
2659+ std::string m_what;
2660+ SourceLineInfo m_lineInfo;
2661+ };
2662+
2663+} // end namespace Catch
2664+
2665+///////////////////////////////////////////////////////////////////////////////
2666+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
2667+
2668+// #included from: internal/catch_context.h
2669+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
2670+
2671+// #included from: catch_interfaces_generators.h
2672+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
2673+
2674+#include <string>
2675+
2676+namespace Catch {
2677+
2678+ struct IGeneratorInfo {
2679+ virtual ~IGeneratorInfo();
2680+ virtual bool moveNext() = 0;
2681+ virtual std::size_t getCurrentIndex() const = 0;
2682+ };
2683+
2684+ struct IGeneratorsForTest {
2685+ virtual ~IGeneratorsForTest();
2686+
2687+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
2688+ virtual bool moveNext() = 0;
2689+ };
2690+
2691+ IGeneratorsForTest* createGeneratorsForTest();
2692+
2693+} // end namespace Catch
2694+
2695+// #included from: catch_ptr.hpp
2696+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
2697+
2698+#ifdef __clang__
2699+#pragma clang diagnostic push
2700+#pragma clang diagnostic ignored "-Wpadded"
2701+#endif
2702+
2703+namespace Catch {
2704+
2705+ // An intrusive reference counting smart pointer.
2706+ // T must implement addRef() and release() methods
2707+ // typically implementing the IShared interface
2708+ template<typename T>
2709+ class Ptr {
2710+ public:
2711+ Ptr() : m_p( CATCH_NULL ){}
2712+ Ptr( T* p ) : m_p( p ){
2713+ if( m_p )
2714+ m_p->addRef();
2715+ }
2716+ Ptr( Ptr const& other ) : m_p( other.m_p ){
2717+ if( m_p )
2718+ m_p->addRef();
2719+ }
2720+ ~Ptr(){
2721+ if( m_p )
2722+ m_p->release();
2723+ }
2724+ void reset() {
2725+ if( m_p )
2726+ m_p->release();
2727+ m_p = CATCH_NULL;
2728+ }
2729+ Ptr& operator = ( T* p ){
2730+ Ptr temp( p );
2731+ swap( temp );
2732+ return *this;
2733+ }
2734+ Ptr& operator = ( Ptr const& other ){
2735+ Ptr temp( other );
2736+ swap( temp );
2737+ return *this;
2738+ }
2739+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
2740+ T* get() const{ return m_p; }
2741+ T& operator*() const { return *m_p; }
2742+ T* operator->() const { return m_p; }
2743+ bool operator !() const { return m_p == CATCH_NULL; }
2744+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
2745+
2746+ private:
2747+ T* m_p;
2748+ };
2749+
2750+ struct IShared : NonCopyable {
2751+ virtual ~IShared();
2752+ virtual void addRef() const = 0;
2753+ virtual void release() const = 0;
2754+ };
2755+
2756+ template<typename T = IShared>
2757+ struct SharedImpl : T {
2758+
2759+ SharedImpl() : m_rc( 0 ){}
2760+
2761+ virtual void addRef() const {
2762+ ++m_rc;
2763+ }
2764+ virtual void release() const {
2765+ if( --m_rc == 0 )
2766+ delete this;
2767+ }
2768+
2769+ mutable unsigned int m_rc;
2770+ };
2771+
2772+} // end namespace Catch
2773+
2774+#ifdef __clang__
2775+#pragma clang diagnostic pop
2776+#endif
2777+
2778+#include <memory>
2779+#include <vector>
2780+#include <stdlib.h>
2781+
2782+namespace Catch {
2783+
2784+ class TestCase;
2785+ class Stream;
2786+ struct IResultCapture;
2787+ struct IRunner;
2788+ struct IGeneratorsForTest;
2789+ struct IConfig;
2790+
2791+ struct IContext
2792+ {
2793+ virtual ~IContext();
2794+
2795+ virtual IResultCapture* getResultCapture() = 0;
2796+ virtual IRunner* getRunner() = 0;
2797+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
2798+ virtual bool advanceGeneratorsForCurrentTest() = 0;
2799+ virtual Ptr<IConfig const> getConfig() const = 0;
2800+ };
2801+
2802+ struct IMutableContext : IContext
2803+ {
2804+ virtual ~IMutableContext();
2805+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
2806+ virtual void setRunner( IRunner* runner ) = 0;
2807+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
2808+ };
2809+
2810+ IContext& getCurrentContext();
2811+ IMutableContext& getCurrentMutableContext();
2812+ void cleanUpContext();
2813+ Stream createStream( std::string const& streamName );
2814+
2815+}
2816+
2817+// #included from: internal/catch_test_registry.hpp
2818+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
2819+
2820+// #included from: catch_interfaces_testcase.h
2821+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
2822+
2823+#include <vector>
2824+
2825+namespace Catch {
2826+
2827+ class TestSpec;
2828+
2829+ struct ITestCase : IShared {
2830+ virtual void invoke () const = 0;
2831+ protected:
2832+ virtual ~ITestCase();
2833+ };
2834+
2835+ class TestCase;
2836+ struct IConfig;
2837+
2838+ struct ITestCaseRegistry {
2839+ virtual ~ITestCaseRegistry();
2840+ virtual std::vector<TestCase> const& getAllTests() const = 0;
2841+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
2842+ };
2843+
2844+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
2845+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
2846+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
2847+
2848+}
2849+
2850+namespace Catch {
2851+
2852+template<typename C>
2853+class MethodTestCase : public SharedImpl<ITestCase> {
2854+
2855+public:
2856+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
2857+
2858+ virtual void invoke() const {
2859+ C obj;
2860+ (obj.*m_method)();
2861+ }
2862+
2863+private:
2864+ virtual ~MethodTestCase() {}
2865+
2866+ void (C::*m_method)();
2867+};
2868+
2869+typedef void(*TestFunction)();
2870+
2871+struct NameAndDesc {
2872+ NameAndDesc( const char* _name = "", const char* _description= "" )
2873+ : name( _name ), description( _description )
2874+ {}
2875+
2876+ const char* name;
2877+ const char* description;
2878+};
2879+
2880+void registerTestCase
2881+ ( ITestCase* testCase,
2882+ char const* className,
2883+ NameAndDesc const& nameAndDesc,
2884+ SourceLineInfo const& lineInfo );
2885+
2886+struct AutoReg {
2887+
2888+ AutoReg
2889+ ( TestFunction function,
2890+ SourceLineInfo const& lineInfo,
2891+ NameAndDesc const& nameAndDesc );
2892+
2893+ template<typename C>
2894+ AutoReg
2895+ ( void (C::*method)(),
2896+ char const* className,
2897+ NameAndDesc const& nameAndDesc,
2898+ SourceLineInfo const& lineInfo ) {
2899+
2900+ registerTestCase
2901+ ( new MethodTestCase<C>( method ),
2902+ className,
2903+ nameAndDesc,
2904+ lineInfo );
2905+ }
2906+
2907+ ~AutoReg();
2908+
2909+private:
2910+ AutoReg( AutoReg const& );
2911+ void operator= ( AutoReg const& );
2912+};
2913+
2914+void registerTestCaseFunction
2915+ ( TestFunction function,
2916+ SourceLineInfo const& lineInfo,
2917+ NameAndDesc const& nameAndDesc );
2918+
2919+} // end namespace Catch
2920+
2921+#ifdef CATCH_CONFIG_VARIADIC_MACROS
2922+ ///////////////////////////////////////////////////////////////////////////////
2923+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
2924+ static void TestName(); \
2925+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
2926+ static void TestName()
2927+ #define INTERNAL_CATCH_TESTCASE( ... ) \
2928+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
2929+
2930+ ///////////////////////////////////////////////////////////////////////////////
2931+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
2932+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
2933+
2934+ ///////////////////////////////////////////////////////////////////////////////
2935+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
2936+ namespace{ \
2937+ struct TestName : ClassName{ \
2938+ void test(); \
2939+ }; \
2940+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
2941+ } \
2942+ void TestName::test()
2943+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
2944+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
2945+
2946+ ///////////////////////////////////////////////////////////////////////////////
2947+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
2948+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
2949+
2950+#else
2951+ ///////////////////////////////////////////////////////////////////////////////
2952+ #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
2953+ static void TestName(); \
2954+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
2955+ static void TestName()
2956+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
2957+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
2958+
2959+ ///////////////////////////////////////////////////////////////////////////////
2960+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
2961+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
2962+
2963+ ///////////////////////////////////////////////////////////////////////////////
2964+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
2965+ namespace{ \
2966+ struct TestCaseName : ClassName{ \
2967+ void test(); \
2968+ }; \
2969+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
2970+ } \
2971+ void TestCaseName::test()
2972+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
2973+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
2974+
2975+ ///////////////////////////////////////////////////////////////////////////////
2976+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
2977+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
2978+#endif
2979+
2980+// #included from: internal/catch_capture.hpp
2981+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
2982+
2983+// #included from: catch_result_builder.h
2984+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
2985+
2986+// #included from: catch_result_type.h
2987+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
2988+
2989+namespace Catch {
2990+
2991+ // ResultWas::OfType enum
2992+ struct ResultWas { enum OfType {
2993+ Unknown = -1,
2994+ Ok = 0,
2995+ Info = 1,
2996+ Warning = 2,
2997+
2998+ FailureBit = 0x10,
2999+
3000+ ExpressionFailed = FailureBit | 1,
3001+ ExplicitFailure = FailureBit | 2,
3002+
3003+ Exception = 0x100 | FailureBit,
3004+
3005+ ThrewException = Exception | 1,
3006+ DidntThrowException = Exception | 2,
3007+
3008+ FatalErrorCondition = 0x200 | FailureBit
3009+
3010+ }; };
3011+
3012+ inline bool isOk( ResultWas::OfType resultType ) {
3013+ return ( resultType & ResultWas::FailureBit ) == 0;
3014+ }
3015+ inline bool isJustInfo( int flags ) {
3016+ return flags == ResultWas::Info;
3017+ }
3018+
3019+ // ResultDisposition::Flags enum
3020+ struct ResultDisposition { enum Flags {
3021+ Normal = 0x01,
3022+
3023+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
3024+ FalseTest = 0x04, // Prefix expression with !
3025+ SuppressFail = 0x08 // Failures are reported but do not fail the test
3026+ }; };
3027+
3028+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
3029+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
3030+ }
3031+
3032+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
3033+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
3034+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
3035+
3036+} // end namespace Catch
3037+
3038+// #included from: catch_assertionresult.h
3039+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
3040+
3041+#include <string>
3042+
3043+namespace Catch {
3044+
3045+ struct AssertionInfo
3046+ {
3047+ AssertionInfo() {}
3048+ AssertionInfo( std::string const& _macroName,
3049+ SourceLineInfo const& _lineInfo,
3050+ std::string const& _capturedExpression,
3051+ ResultDisposition::Flags _resultDisposition );
3052+
3053+ std::string macroName;
3054+ SourceLineInfo lineInfo;
3055+ std::string capturedExpression;
3056+ ResultDisposition::Flags resultDisposition;
3057+ };
3058+
3059+ struct AssertionResultData
3060+ {
3061+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
3062+
3063+ std::string reconstructedExpression;
3064+ std::string message;
3065+ ResultWas::OfType resultType;
3066+ };
3067+
3068+ class AssertionResult {
3069+ public:
3070+ AssertionResult();
3071+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
3072+ ~AssertionResult();
3073+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
3074+ AssertionResult( AssertionResult const& ) = default;
3075+ AssertionResult( AssertionResult && ) = default;
3076+ AssertionResult& operator = ( AssertionResult const& ) = default;
3077+ AssertionResult& operator = ( AssertionResult && ) = default;
3078+# endif
3079+
3080+ bool isOk() const;
3081+ bool succeeded() const;
3082+ ResultWas::OfType getResultType() const;
3083+ bool hasExpression() const;
3084+ bool hasMessage() const;
3085+ std::string getExpression() const;
3086+ std::string getExpressionInMacro() const;
3087+ bool hasExpandedExpression() const;
3088+ std::string getExpandedExpression() const;
3089+ std::string getMessage() const;
3090+ SourceLineInfo getSourceInfo() const;
3091+ std::string getTestMacroName() const;
3092+
3093+ protected:
3094+ AssertionInfo m_info;
3095+ AssertionResultData m_resultData;
3096+ };
3097+
3098+} // end namespace Catch
3099+
3100+// #included from: catch_matchers.hpp
3101+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
3102+
3103+namespace Catch {
3104+namespace Matchers {
3105+ namespace Impl {
3106+
3107+ namespace Generic {
3108+ template<typename ExpressionT> class AllOf;
3109+ template<typename ExpressionT> class AnyOf;
3110+ template<typename ExpressionT> class Not;
3111+ }
3112+
3113+ template<typename ExpressionT>
3114+ struct Matcher : SharedImpl<IShared>
3115+ {
3116+ typedef ExpressionT ExpressionType;
3117+
3118+ virtual ~Matcher() {}
3119+ virtual Ptr<Matcher> clone() const = 0;
3120+ virtual bool match( ExpressionT const& expr ) const = 0;
3121+ virtual std::string toString() const = 0;
3122+
3123+ Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
3124+ Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
3125+ Generic::Not<ExpressionT> operator ! () const;
3126+ };
3127+
3128+ template<typename DerivedT, typename ExpressionT>
3129+ struct MatcherImpl : Matcher<ExpressionT> {
3130+
3131+ virtual Ptr<Matcher<ExpressionT> > clone() const {
3132+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
3133+ }
3134+ };
3135+
3136+ namespace Generic {
3137+ template<typename ExpressionT>
3138+ class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
3139+ public:
3140+ explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
3141+ Not( Not const& other ) : m_matcher( other.m_matcher ) {}
3142+
3143+ virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
3144+ return !m_matcher->match( expr );
3145+ }
3146+
3147+ virtual std::string toString() const CATCH_OVERRIDE {
3148+ return "not " + m_matcher->toString();
3149+ }
3150+ private:
3151+ Ptr< Matcher<ExpressionT> > m_matcher;
3152+ };
3153+
3154+ template<typename ExpressionT>
3155+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
3156+ public:
3157+
3158+ AllOf() {}
3159+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
3160+
3161+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
3162+ m_matchers.push_back( matcher.clone() );
3163+ return *this;
3164+ }
3165+ virtual bool match( ExpressionT const& expr ) const
3166+ {
3167+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
3168+ if( !m_matchers[i]->match( expr ) )
3169+ return false;
3170+ return true;
3171+ }
3172+ virtual std::string toString() const {
3173+ std::ostringstream oss;
3174+ oss << "( ";
3175+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3176+ if( i != 0 )
3177+ oss << " and ";
3178+ oss << m_matchers[i]->toString();
3179+ }
3180+ oss << " )";
3181+ return oss.str();
3182+ }
3183+
3184+ AllOf operator && ( Matcher<ExpressionT> const& other ) const {
3185+ AllOf allOfExpr( *this );
3186+ allOfExpr.add( other );
3187+ return allOfExpr;
3188+ }
3189+
3190+ private:
3191+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3192+ };
3193+
3194+ template<typename ExpressionT>
3195+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
3196+ public:
3197+
3198+ AnyOf() {}
3199+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
3200+
3201+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
3202+ m_matchers.push_back( matcher.clone() );
3203+ return *this;
3204+ }
3205+ virtual bool match( ExpressionT const& expr ) const
3206+ {
3207+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
3208+ if( m_matchers[i]->match( expr ) )
3209+ return true;
3210+ return false;
3211+ }
3212+ virtual std::string toString() const {
3213+ std::ostringstream oss;
3214+ oss << "( ";
3215+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3216+ if( i != 0 )
3217+ oss << " or ";
3218+ oss << m_matchers[i]->toString();
3219+ }
3220+ oss << " )";
3221+ return oss.str();
3222+ }
3223+
3224+ AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
3225+ AnyOf anyOfExpr( *this );
3226+ anyOfExpr.add( other );
3227+ return anyOfExpr;
3228+ }
3229+
3230+ private:
3231+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3232+ };
3233+
3234+ } // namespace Generic
3235+
3236+ template<typename ExpressionT>
3237+ Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
3238+ Generic::AllOf<ExpressionT> allOfExpr;
3239+ allOfExpr.add( *this );
3240+ allOfExpr.add( other );
3241+ return allOfExpr;
3242+ }
3243+
3244+ template<typename ExpressionT>
3245+ Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
3246+ Generic::AnyOf<ExpressionT> anyOfExpr;
3247+ anyOfExpr.add( *this );
3248+ anyOfExpr.add( other );
3249+ return anyOfExpr;
3250+ }
3251+
3252+ template<typename ExpressionT>
3253+ Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
3254+ return Generic::Not<ExpressionT>( *this );
3255+ }
3256+
3257+ namespace StdString {
3258+
3259+ inline std::string makeString( std::string const& str ) { return str; }
3260+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
3261+
3262+ struct CasedString
3263+ {
3264+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
3265+ : m_caseSensitivity( caseSensitivity ),
3266+ m_str( adjustString( str ) )
3267+ {}
3268+ std::string adjustString( std::string const& str ) const {
3269+ return m_caseSensitivity == CaseSensitive::No
3270+ ? toLower( str )
3271+ : str;
3272+
3273+ }
3274+ std::string toStringSuffix() const
3275+ {
3276+ return m_caseSensitivity == CaseSensitive::No
3277+ ? " (case insensitive)"
3278+ : "";
3279+ }
3280+ CaseSensitive::Choice m_caseSensitivity;
3281+ std::string m_str;
3282+ };
3283+
3284+ struct Equals : MatcherImpl<Equals, std::string> {
3285+ Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
3286+ : m_data( str, caseSensitivity )
3287+ {}
3288+ Equals( Equals const& other ) : m_data( other.m_data ){}
3289+
3290+ virtual ~Equals();
3291+
3292+ virtual bool match( std::string const& expr ) const {
3293+ return m_data.m_str == m_data.adjustString( expr );;
3294+ }
3295+ virtual std::string toString() const {
3296+ return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
3297+ }
3298+
3299+ CasedString m_data;
3300+ };
3301+
3302+ struct Contains : MatcherImpl<Contains, std::string> {
3303+ Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
3304+ : m_data( substr, caseSensitivity ){}
3305+ Contains( Contains const& other ) : m_data( other.m_data ){}
3306+
3307+ virtual ~Contains();
3308+
3309+ virtual bool match( std::string const& expr ) const {
3310+ return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
3311+ }
3312+ virtual std::string toString() const {
3313+ return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
3314+ }
3315+
3316+ CasedString m_data;
3317+ };
3318+
3319+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
3320+ StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
3321+ : m_data( substr, caseSensitivity ){}
3322+
3323+ StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
3324+
3325+ virtual ~StartsWith();
3326+
3327+ virtual bool match( std::string const& expr ) const {
3328+ return startsWith( m_data.adjustString( expr ), m_data.m_str );
3329+ }
3330+ virtual std::string toString() const {
3331+ return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
3332+ }
3333+
3334+ CasedString m_data;
3335+ };
3336+
3337+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
3338+ EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
3339+ : m_data( substr, caseSensitivity ){}
3340+ EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
3341+
3342+ virtual ~EndsWith();
3343+
3344+ virtual bool match( std::string const& expr ) const {
3345+ return endsWith( m_data.adjustString( expr ), m_data.m_str );
3346+ }
3347+ virtual std::string toString() const {
3348+ return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
3349+ }
3350+
3351+ CasedString m_data;
3352+ };
3353+ } // namespace StdString
3354+ } // namespace Impl
3355+
3356+ // The following functions create the actual matcher objects.
3357+ // This allows the types to be inferred
3358+ template<typename ExpressionT>
3359+ inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
3360+ return Impl::Generic::Not<ExpressionT>( m );
3361+ }
3362+
3363+ template<typename ExpressionT>
3364+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
3365+ Impl::Matcher<ExpressionT> const& m2 ) {
3366+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
3367+ }
3368+ template<typename ExpressionT>
3369+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
3370+ Impl::Matcher<ExpressionT> const& m2,
3371+ Impl::Matcher<ExpressionT> const& m3 ) {
3372+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
3373+ }
3374+ template<typename ExpressionT>
3375+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
3376+ Impl::Matcher<ExpressionT> const& m2 ) {
3377+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
3378+ }
3379+ template<typename ExpressionT>
3380+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
3381+ Impl::Matcher<ExpressionT> const& m2,
3382+ Impl::Matcher<ExpressionT> const& m3 ) {
3383+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
3384+ }
3385+
3386+ inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
3387+ return Impl::StdString::Equals( str, caseSensitivity );
3388+ }
3389+ inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
3390+ return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
3391+ }
3392+ inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
3393+ return Impl::StdString::Contains( substr, caseSensitivity );
3394+ }
3395+ inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
3396+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
3397+ }
3398+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
3399+ return Impl::StdString::StartsWith( substr );
3400+ }
3401+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
3402+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
3403+ }
3404+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
3405+ return Impl::StdString::EndsWith( substr );
3406+ }
3407+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
3408+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
3409+ }
3410+
3411+} // namespace Matchers
3412+
3413+using namespace Matchers;
3414+
3415+} // namespace Catch
3416+
3417+namespace Catch {
3418+
3419+ struct TestFailureException{};
3420+
3421+ template<typename T> class ExpressionLhs;
3422+
3423+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
3424+
3425+ struct CopyableStream {
3426+ CopyableStream() {}
3427+ CopyableStream( CopyableStream const& other ) {
3428+ oss << other.oss.str();
3429+ }
3430+ CopyableStream& operator=( CopyableStream const& other ) {
3431+ oss.str("");
3432+ oss << other.oss.str();
3433+ return *this;
3434+ }
3435+ std::ostringstream oss;
3436+ };
3437+
3438+ class ResultBuilder {
3439+ public:
3440+ ResultBuilder( char const* macroName,
3441+ SourceLineInfo const& lineInfo,
3442+ char const* capturedExpression,
3443+ ResultDisposition::Flags resultDisposition,
3444+ char const* secondArg = "" );
3445+
3446+ template<typename T>
3447+ ExpressionLhs<T const&> operator <= ( T const& operand );
3448+ ExpressionLhs<bool> operator <= ( bool value );
3449+
3450+ template<typename T>
3451+ ResultBuilder& operator << ( T const& value ) {
3452+ m_stream.oss << value;
3453+ return *this;
3454+ }
3455+
3456+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
3457+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
3458+
3459+ ResultBuilder& setResultType( ResultWas::OfType result );
3460+ ResultBuilder& setResultType( bool result );
3461+ ResultBuilder& setLhs( std::string const& lhs );
3462+ ResultBuilder& setRhs( std::string const& rhs );
3463+ ResultBuilder& setOp( std::string const& op );
3464+
3465+ void endExpression();
3466+
3467+ std::string reconstructExpression() const;
3468+ AssertionResult build() const;
3469+
3470+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
3471+ void captureResult( ResultWas::OfType resultType );
3472+ void captureExpression();
3473+ void captureExpectedException( std::string const& expectedMessage );
3474+ void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
3475+ void handleResult( AssertionResult const& result );
3476+ void react();
3477+ bool shouldDebugBreak() const;
3478+ bool allowThrows() const;
3479+
3480+ private:
3481+ AssertionInfo m_assertionInfo;
3482+ AssertionResultData m_data;
3483+ struct ExprComponents {
3484+ ExprComponents() : testFalse( false ) {}
3485+ bool testFalse;
3486+ std::string lhs, rhs, op;
3487+ } m_exprComponents;
3488+ CopyableStream m_stream;
3489+
3490+ bool m_shouldDebugBreak;
3491+ bool m_shouldThrow;
3492+ };
3493+
3494+} // namespace Catch
3495+
3496+// Include after due to circular dependency:
3497+// #included from: catch_expression_lhs.hpp
3498+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
3499+
3500+// #included from: catch_evaluate.hpp
3501+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
3502+
3503+#ifdef _MSC_VER
3504+#pragma warning(push)
3505+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
3506+#endif
3507+
3508+#include <cstddef>
3509+
3510+namespace Catch {
3511+namespace Internal {
3512+
3513+ enum Operator {
3514+ IsEqualTo,
3515+ IsNotEqualTo,
3516+ IsLessThan,
3517+ IsGreaterThan,
3518+ IsLessThanOrEqualTo,
3519+ IsGreaterThanOrEqualTo
3520+ };
3521+
3522+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
3523+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
3524+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
3525+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
3526+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
3527+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
3528+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
3529+
3530+ template<typename T>
3531+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
3532+
3533+// nullptr_t support based on pull request #154 from Konstantin Baumann
3534+#ifdef CATCH_CONFIG_CPP11_NULLPTR
3535+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
3536+#endif // CATCH_CONFIG_CPP11_NULLPTR
3537+
3538+ // So the compare overloads can be operator agnostic we convey the operator as a template
3539+ // enum, which is used to specialise an Evaluator for doing the comparison.
3540+ template<typename T1, typename T2, Operator Op>
3541+ class Evaluator{};
3542+
3543+ template<typename T1, typename T2>
3544+ struct Evaluator<T1, T2, IsEqualTo> {
3545+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
3546+ return bool( opCast( lhs ) == opCast( rhs ) );
3547+ }
3548+ };
3549+ template<typename T1, typename T2>
3550+ struct Evaluator<T1, T2, IsNotEqualTo> {
3551+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
3552+ return bool( opCast( lhs ) != opCast( rhs ) );
3553+ }
3554+ };
3555+ template<typename T1, typename T2>
3556+ struct Evaluator<T1, T2, IsLessThan> {
3557+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
3558+ return bool( opCast( lhs ) < opCast( rhs ) );
3559+ }
3560+ };
3561+ template<typename T1, typename T2>
3562+ struct Evaluator<T1, T2, IsGreaterThan> {
3563+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
3564+ return bool( opCast( lhs ) > opCast( rhs ) );
3565+ }
3566+ };
3567+ template<typename T1, typename T2>
3568+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
3569+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
3570+ return bool( opCast( lhs ) >= opCast( rhs ) );
3571+ }
3572+ };
3573+ template<typename T1, typename T2>
3574+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
3575+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
3576+ return bool( opCast( lhs ) <= opCast( rhs ) );
3577+ }
3578+ };
3579+
3580+ template<Operator Op, typename T1, typename T2>
3581+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
3582+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
3583+ }
3584+
3585+ // This level of indirection allows us to specialise for integer types
3586+ // to avoid signed/ unsigned warnings
3587+
3588+ // "base" overload
3589+ template<Operator Op, typename T1, typename T2>
3590+ bool compare( T1 const& lhs, T2 const& rhs ) {
3591+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
3592+ }
3593+
3594+ // unsigned X to int
3595+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
3596+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
3597+ }
3598+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
3599+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
3600+ }
3601+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
3602+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
3603+ }
3604+
3605+ // unsigned X to long
3606+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
3607+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
3608+ }
3609+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
3610+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
3611+ }
3612+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
3613+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
3614+ }
3615+
3616+ // int to unsigned X
3617+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
3618+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
3619+ }
3620+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
3621+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
3622+ }
3623+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
3624+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
3625+ }
3626+
3627+ // long to unsigned X
3628+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
3629+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3630+ }
3631+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
3632+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3633+ }
3634+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
3635+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3636+ }
3637+
3638+ // pointer to long (when comparing against NULL)
3639+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
3640+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
3641+ }
3642+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
3643+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
3644+ }
3645+
3646+ // pointer to int (when comparing against NULL)
3647+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
3648+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
3649+ }
3650+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
3651+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
3652+ }
3653+
3654+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
3655+ // long long to unsigned X
3656+ template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
3657+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3658+ }
3659+ template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
3660+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3661+ }
3662+ template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
3663+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3664+ }
3665+ template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
3666+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
3667+ }
3668+
3669+ // unsigned long long to X
3670+ template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
3671+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
3672+ }
3673+ template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
3674+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
3675+ }
3676+ template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
3677+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
3678+ }
3679+ template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
3680+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
3681+ }
3682+
3683+ // pointer to long long (when comparing against NULL)
3684+ template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
3685+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
3686+ }
3687+ template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
3688+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
3689+ }
3690+#endif // CATCH_CONFIG_CPP11_LONG_LONG
3691+
3692+#ifdef CATCH_CONFIG_CPP11_NULLPTR
3693+ // pointer to nullptr_t (when comparing against nullptr)
3694+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
3695+ return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
3696+ }
3697+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
3698+ return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
3699+ }
3700+#endif // CATCH_CONFIG_CPP11_NULLPTR
3701+
3702+} // end of namespace Internal
3703+} // end of namespace Catch
3704+
3705+#ifdef _MSC_VER
3706+#pragma warning(pop)
3707+#endif
3708+
3709+// #included from: catch_tostring.h
3710+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
3711+
3712+#include <sstream>
3713+#include <iomanip>
3714+#include <limits>
3715+#include <vector>
3716+#include <cstddef>
3717+
3718+#ifdef __OBJC__
3719+// #included from: catch_objc_arc.hpp
3720+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
3721+
3722+#import <Foundation/Foundation.h>
3723+
3724+#ifdef __has_feature
3725+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
3726+#else
3727+#define CATCH_ARC_ENABLED 0
3728+#endif
3729+
3730+void arcSafeRelease( NSObject* obj );
3731+id performOptionalSelector( id obj, SEL sel );
3732+
3733+#if !CATCH_ARC_ENABLED
3734+inline void arcSafeRelease( NSObject* obj ) {
3735+ [obj release];
3736+}
3737+inline id performOptionalSelector( id obj, SEL sel ) {
3738+ if( [obj respondsToSelector: sel] )
3739+ return [obj performSelector: sel];
3740+ return nil;
3741+}
3742+#define CATCH_UNSAFE_UNRETAINED
3743+#define CATCH_ARC_STRONG
3744+#else
3745+inline void arcSafeRelease( NSObject* ){}
3746+inline id performOptionalSelector( id obj, SEL sel ) {
3747+#ifdef __clang__
3748+#pragma clang diagnostic push
3749+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
3750+#endif
3751+ if( [obj respondsToSelector: sel] )
3752+ return [obj performSelector: sel];
3753+#ifdef __clang__
3754+#pragma clang diagnostic pop
3755+#endif
3756+ return nil;
3757+}
3758+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
3759+#define CATCH_ARC_STRONG __strong
3760+#endif
3761+
3762+#endif
3763+
3764+#ifdef CATCH_CONFIG_CPP11_TUPLE
3765+#include <tuple>
3766+#endif
3767+
3768+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
3769+#include <type_traits>
3770+#endif
3771+
3772+namespace Catch {
3773+
3774+// Why we're here.
3775+template<typename T>
3776+std::string toString( T const& value );
3777+
3778+// Built in overloads
3779+
3780+std::string toString( std::string const& value );
3781+std::string toString( std::wstring const& value );
3782+std::string toString( const char* const value );
3783+std::string toString( char* const value );
3784+std::string toString( const wchar_t* const value );
3785+std::string toString( wchar_t* const value );
3786+std::string toString( int value );
3787+std::string toString( unsigned long value );
3788+std::string toString( unsigned int value );
3789+std::string toString( const double value );
3790+std::string toString( const float value );
3791+std::string toString( bool value );
3792+std::string toString( char value );
3793+std::string toString( signed char value );
3794+std::string toString( unsigned char value );
3795+
3796+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
3797+std::string toString( long long value );
3798+std::string toString( unsigned long long value );
3799+#endif
3800+
3801+#ifdef CATCH_CONFIG_CPP11_NULLPTR
3802+std::string toString( std::nullptr_t );
3803+#endif
3804+
3805+#ifdef __OBJC__
3806+ std::string toString( NSString const * const& nsstring );
3807+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
3808+ std::string toString( NSObject* const& nsObject );
3809+#endif
3810+
3811+namespace Detail {
3812+
3813+ extern const std::string unprintableString;
3814+
3815+ struct BorgType {
3816+ template<typename T> BorgType( T const& );
3817+ };
3818+
3819+ struct TrueType { char sizer[1]; };
3820+ struct FalseType { char sizer[2]; };
3821+
3822+ TrueType& testStreamable( std::ostream& );
3823+ FalseType testStreamable( FalseType );
3824+
3825+ FalseType operator<<( std::ostream const&, BorgType const& );
3826+
3827+ template<typename T>
3828+ struct IsStreamInsertable {
3829+ static std::ostream &s;
3830+ static T const&t;
3831+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
3832+ };
3833+
3834+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
3835+ template<typename T,
3836+ bool IsEnum = std::is_enum<T>::value
3837+ >
3838+ struct EnumStringMaker
3839+ {
3840+ static std::string convert( T const& ) { return unprintableString; }
3841+ };
3842+
3843+ template<typename T>
3844+ struct EnumStringMaker<T,true>
3845+ {
3846+ static std::string convert( T const& v )
3847+ {
3848+ return ::Catch::toString(
3849+ static_cast<typename std::underlying_type<T>::type>(v)
3850+ );
3851+ }
3852+ };
3853+#endif
3854+ template<bool C>
3855+ struct StringMakerBase {
3856+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
3857+ template<typename T>
3858+ static std::string convert( T const& v )
3859+ {
3860+ return EnumStringMaker<T>::convert( v );
3861+ }
3862+#else
3863+ template<typename T>
3864+ static std::string convert( T const& ) { return unprintableString; }
3865+#endif
3866+ };
3867+
3868+ template<>
3869+ struct StringMakerBase<true> {
3870+ template<typename T>
3871+ static std::string convert( T const& _value ) {
3872+ std::ostringstream oss;
3873+ oss << _value;
3874+ return oss.str();
3875+ }
3876+ };
3877+
3878+ std::string rawMemoryToString( const void *object, std::size_t size );
3879+
3880+ template<typename T>
3881+ inline std::string rawMemoryToString( const T& object ) {
3882+ return rawMemoryToString( &object, sizeof(object) );
3883+ }
3884+
3885+} // end namespace Detail
3886+
3887+template<typename T>
3888+struct StringMaker :
3889+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
3890+
3891+template<typename T>
3892+struct StringMaker<T*> {
3893+ template<typename U>
3894+ static std::string convert( U* p ) {
3895+ if( !p )
3896+ return "NULL";
3897+ else
3898+ return Detail::rawMemoryToString( p );
3899+ }
3900+};
3901+
3902+template<typename R, typename C>
3903+struct StringMaker<R C::*> {
3904+ static std::string convert( R C::* p ) {
3905+ if( !p )
3906+ return "NULL";
3907+ else
3908+ return Detail::rawMemoryToString( p );
3909+ }
3910+};
3911+
3912+namespace Detail {
3913+ template<typename InputIterator>
3914+ std::string rangeToString( InputIterator first, InputIterator last );
3915+}
3916+
3917+//template<typename T, typename Allocator>
3918+//struct StringMaker<std::vector<T, Allocator> > {
3919+// static std::string convert( std::vector<T,Allocator> const& v ) {
3920+// return Detail::rangeToString( v.begin(), v.end() );
3921+// }
3922+//};
3923+
3924+template<typename T, typename Allocator>
3925+std::string toString( std::vector<T,Allocator> const& v ) {
3926+ return Detail::rangeToString( v.begin(), v.end() );
3927+}
3928+
3929+#ifdef CATCH_CONFIG_CPP11_TUPLE
3930+
3931+// toString for tuples
3932+namespace TupleDetail {
3933+ template<
3934+ typename Tuple,
3935+ std::size_t N = 0,
3936+ bool = (N < std::tuple_size<Tuple>::value)
3937+ >
3938+ struct ElementPrinter {
3939+ static void print( const Tuple& tuple, std::ostream& os )
3940+ {
3941+ os << ( N ? ", " : " " )
3942+ << Catch::toString(std::get<N>(tuple));
3943+ ElementPrinter<Tuple,N+1>::print(tuple,os);
3944+ }
3945+ };
3946+
3947+ template<
3948+ typename Tuple,
3949+ std::size_t N
3950+ >
3951+ struct ElementPrinter<Tuple,N,false> {
3952+ static void print( const Tuple&, std::ostream& ) {}
3953+ };
3954+
3955+}
3956+
3957+template<typename ...Types>
3958+struct StringMaker<std::tuple<Types...>> {
3959+
3960+ static std::string convert( const std::tuple<Types...>& tuple )
3961+ {
3962+ std::ostringstream os;
3963+ os << '{';
3964+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
3965+ os << " }";
3966+ return os.str();
3967+ }
3968+};
3969+#endif // CATCH_CONFIG_CPP11_TUPLE
3970+
3971+namespace Detail {
3972+ template<typename T>
3973+ std::string makeString( T const& value ) {
3974+ return StringMaker<T>::convert( value );
3975+ }
3976+} // end namespace Detail
3977+
3978+/// \brief converts any type to a string
3979+///
3980+/// The default template forwards on to ostringstream - except when an
3981+/// ostringstream overload does not exist - in which case it attempts to detect
3982+/// that and writes {?}.
3983+/// Overload (not specialise) this template for custom typs that you don't want
3984+/// to provide an ostream overload for.
3985+template<typename T>
3986+std::string toString( T const& value ) {
3987+ return StringMaker<T>::convert( value );
3988+}
3989+
3990+ namespace Detail {
3991+ template<typename InputIterator>
3992+ std::string rangeToString( InputIterator first, InputIterator last ) {
3993+ std::ostringstream oss;
3994+ oss << "{ ";
3995+ if( first != last ) {
3996+ oss << Catch::toString( *first );
3997+ for( ++first ; first != last ; ++first )
3998+ oss << ", " << Catch::toString( *first );
3999+ }
4000+ oss << " }";
4001+ return oss.str();
4002+ }
4003+}
4004+
4005+} // end namespace Catch
4006+
4007+namespace Catch {
4008+
4009+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
4010+// wrapping them all in a ResultBuilder object
4011+template<typename T>
4012+class ExpressionLhs {
4013+ ExpressionLhs& operator = ( ExpressionLhs const& );
4014+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4015+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
4016+# endif
4017+
4018+public:
4019+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
4020+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4021+ ExpressionLhs( ExpressionLhs const& ) = default;
4022+ ExpressionLhs( ExpressionLhs && ) = default;
4023+# endif
4024+
4025+ template<typename RhsT>
4026+ ResultBuilder& operator == ( RhsT const& rhs ) {
4027+ return captureExpression<Internal::IsEqualTo>( rhs );
4028+ }
4029+
4030+ template<typename RhsT>
4031+ ResultBuilder& operator != ( RhsT const& rhs ) {
4032+ return captureExpression<Internal::IsNotEqualTo>( rhs );
4033+ }
4034+
4035+ template<typename RhsT>
4036+ ResultBuilder& operator < ( RhsT const& rhs ) {
4037+ return captureExpression<Internal::IsLessThan>( rhs );
4038+ }
4039+
4040+ template<typename RhsT>
4041+ ResultBuilder& operator > ( RhsT const& rhs ) {
4042+ return captureExpression<Internal::IsGreaterThan>( rhs );
4043+ }
4044+
4045+ template<typename RhsT>
4046+ ResultBuilder& operator <= ( RhsT const& rhs ) {
4047+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
4048+ }
4049+
4050+ template<typename RhsT>
4051+ ResultBuilder& operator >= ( RhsT const& rhs ) {
4052+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
4053+ }
4054+
4055+ ResultBuilder& operator == ( bool rhs ) {
4056+ return captureExpression<Internal::IsEqualTo>( rhs );
4057+ }
4058+
4059+ ResultBuilder& operator != ( bool rhs ) {
4060+ return captureExpression<Internal::IsNotEqualTo>( rhs );
4061+ }
4062+
4063+ void endExpression() {
4064+ bool value = m_lhs ? true : false;
4065+ m_rb
4066+ .setLhs( Catch::toString( value ) )
4067+ .setResultType( value )
4068+ .endExpression();
4069+ }
4070+
4071+ // Only simple binary expressions are allowed on the LHS.
4072+ // If more complex compositions are required then place the sub expression in parentheses
4073+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
4074+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
4075+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
4076+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
4077+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
4078+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
4079+
4080+private:
4081+ template<Internal::Operator Op, typename RhsT>
4082+ ResultBuilder& captureExpression( RhsT const& rhs ) {
4083+ return m_rb
4084+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
4085+ .setLhs( Catch::toString( m_lhs ) )
4086+ .setRhs( Catch::toString( rhs ) )
4087+ .setOp( Internal::OperatorTraits<Op>::getName() );
4088+ }
4089+
4090+private:
4091+ ResultBuilder& m_rb;
4092+ T m_lhs;
4093+};
4094+
4095+} // end namespace Catch
4096+
4097+
4098+namespace Catch {
4099+
4100+ template<typename T>
4101+ inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
4102+ return ExpressionLhs<T const&>( *this, operand );
4103+ }
4104+
4105+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
4106+ return ExpressionLhs<bool>( *this, value );
4107+ }
4108+
4109+} // namespace Catch
4110+
4111+// #included from: catch_message.h
4112+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
4113+
4114+#include <string>
4115+
4116+namespace Catch {
4117+
4118+ struct MessageInfo {
4119+ MessageInfo( std::string const& _macroName,
4120+ SourceLineInfo const& _lineInfo,
4121+ ResultWas::OfType _type );
4122+
4123+ std::string macroName;
4124+ SourceLineInfo lineInfo;
4125+ ResultWas::OfType type;
4126+ std::string message;
4127+ unsigned int sequence;
4128+
4129+ bool operator == ( MessageInfo const& other ) const {
4130+ return sequence == other.sequence;
4131+ }
4132+ bool operator < ( MessageInfo const& other ) const {
4133+ return sequence < other.sequence;
4134+ }
4135+ private:
4136+ static unsigned int globalCount;
4137+ };
4138+
4139+ struct MessageBuilder {
4140+ MessageBuilder( std::string const& macroName,
4141+ SourceLineInfo const& lineInfo,
4142+ ResultWas::OfType type )
4143+ : m_info( macroName, lineInfo, type )
4144+ {}
4145+
4146+ template<typename T>
4147+ MessageBuilder& operator << ( T const& value ) {
4148+ m_stream << value;
4149+ return *this;
4150+ }
4151+
4152+ MessageInfo m_info;
4153+ std::ostringstream m_stream;
4154+ };
4155+
4156+ class ScopedMessage {
4157+ public:
4158+ ScopedMessage( MessageBuilder const& builder );
4159+ ScopedMessage( ScopedMessage const& other );
4160+ ~ScopedMessage();
4161+
4162+ MessageInfo m_info;
4163+ };
4164+
4165+} // end namespace Catch
4166+
4167+// #included from: catch_interfaces_capture.h
4168+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
4169+
4170+#include <string>
4171+
4172+namespace Catch {
4173+
4174+ class TestCase;
4175+ class AssertionResult;
4176+ struct AssertionInfo;
4177+ struct SectionInfo;
4178+ struct SectionEndInfo;
4179+ struct MessageInfo;
4180+ class ScopedMessageBuilder;
4181+ struct Counts;
4182+
4183+ struct IResultCapture {
4184+
4185+ virtual ~IResultCapture();
4186+
4187+ virtual void assertionEnded( AssertionResult const& result ) = 0;
4188+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
4189+ Counts& assertions ) = 0;
4190+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
4191+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
4192+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
4193+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
4194+
4195+ virtual std::string getCurrentTestName() const = 0;
4196+ virtual const AssertionResult* getLastResult() const = 0;
4197+
4198+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
4199+ };
4200+
4201+ IResultCapture& getResultCapture();
4202+}
4203+
4204+// #included from: catch_debugger.h
4205+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
4206+
4207+// #included from: catch_platform.h
4208+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
4209+
4210+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
4211+#define CATCH_PLATFORM_MAC
4212+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
4213+#define CATCH_PLATFORM_IPHONE
4214+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
4215+#define CATCH_PLATFORM_WINDOWS
4216+#endif
4217+
4218+#include <string>
4219+
4220+namespace Catch{
4221+
4222+ bool isDebuggerActive();
4223+ void writeToDebugConsole( std::string const& text );
4224+}
4225+
4226+#ifdef CATCH_PLATFORM_MAC
4227+
4228+ // The following code snippet based on:
4229+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
4230+ #ifdef DEBUG
4231+ #if defined(__ppc64__) || defined(__ppc__)
4232+ #define CATCH_BREAK_INTO_DEBUGGER() \
4233+ if( Catch::isDebuggerActive() ) { \
4234+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
4235+ : : : "memory","r0","r3","r4" ); \
4236+ }
4237+ #else
4238+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
4239+ #endif
4240+ #endif
4241+
4242+#elif defined(_MSC_VER)
4243+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
4244+#elif defined(__MINGW32__)
4245+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
4246+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
4247+#endif
4248+
4249+#ifndef CATCH_BREAK_INTO_DEBUGGER
4250+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
4251+#endif
4252+
4253+// #included from: catch_interfaces_runner.h
4254+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
4255+
4256+namespace Catch {
4257+ class TestCase;
4258+
4259+ struct IRunner {
4260+ virtual ~IRunner();
4261+ virtual bool aborting() const = 0;
4262+ };
4263+}
4264+
4265+///////////////////////////////////////////////////////////////////////////////
4266+// In the event of a failure works out if the debugger needs to be invoked
4267+// and/or an exception thrown and takes appropriate action.
4268+// This needs to be done as a macro so the debugger will stop in the user
4269+// source code rather than in Catch library code
4270+#define INTERNAL_CATCH_REACT( resultBuilder ) \
4271+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
4272+ resultBuilder.react();
4273+
4274+///////////////////////////////////////////////////////////////////////////////
4275+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
4276+ do { \
4277+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
4278+ try { \
4279+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
4280+ ( __catchResult <= expr ).endExpression(); \
4281+ } \
4282+ catch( ... ) { \
4283+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
4284+ } \
4285+ INTERNAL_CATCH_REACT( __catchResult ) \
4286+ } while( Catch::isTrue( false && static_cast<bool>(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
4287+
4288+///////////////////////////////////////////////////////////////////////////////
4289+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
4290+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
4291+ if( Catch::getResultCapture().getLastResult()->succeeded() )
4292+
4293+///////////////////////////////////////////////////////////////////////////////
4294+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
4295+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
4296+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
4297+
4298+///////////////////////////////////////////////////////////////////////////////
4299+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
4300+ do { \
4301+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
4302+ try { \
4303+ expr; \
4304+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
4305+ } \
4306+ catch( ... ) { \
4307+ __catchResult.useActiveException( resultDisposition ); \
4308+ } \
4309+ INTERNAL_CATCH_REACT( __catchResult ) \
4310+ } while( Catch::alwaysFalse() )
4311+
4312+///////////////////////////////////////////////////////////////////////////////
4313+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
4314+ do { \
4315+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
4316+ if( __catchResult.allowThrows() ) \
4317+ try { \
4318+ expr; \
4319+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
4320+ } \
4321+ catch( ... ) { \
4322+ __catchResult.captureExpectedException( matcher ); \
4323+ } \
4324+ else \
4325+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
4326+ INTERNAL_CATCH_REACT( __catchResult ) \
4327+ } while( Catch::alwaysFalse() )
4328+
4329+///////////////////////////////////////////////////////////////////////////////
4330+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
4331+ do { \
4332+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
4333+ if( __catchResult.allowThrows() ) \
4334+ try { \
4335+ expr; \
4336+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
4337+ } \
4338+ catch( exceptionType ) { \
4339+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
4340+ } \
4341+ catch( ... ) { \
4342+ __catchResult.useActiveException( resultDisposition ); \
4343+ } \
4344+ else \
4345+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
4346+ INTERNAL_CATCH_REACT( __catchResult ) \
4347+ } while( Catch::alwaysFalse() )
4348+
4349+///////////////////////////////////////////////////////////////////////////////
4350+#ifdef CATCH_CONFIG_VARIADIC_MACROS
4351+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
4352+ do { \
4353+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
4354+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
4355+ __catchResult.captureResult( messageType ); \
4356+ INTERNAL_CATCH_REACT( __catchResult ) \
4357+ } while( Catch::alwaysFalse() )
4358+#else
4359+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
4360+ do { \
4361+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
4362+ __catchResult << log + ::Catch::StreamEndStop(); \
4363+ __catchResult.captureResult( messageType ); \
4364+ INTERNAL_CATCH_REACT( __catchResult ) \
4365+ } while( Catch::alwaysFalse() )
4366+#endif
4367+
4368+///////////////////////////////////////////////////////////////////////////////
4369+#define INTERNAL_CATCH_INFO( log, macroName ) \
4370+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
4371+
4372+///////////////////////////////////////////////////////////////////////////////
4373+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
4374+ do { \
4375+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
4376+ try { \
4377+ std::string matcherAsString = (matcher).toString(); \
4378+ __catchResult \
4379+ .setLhs( Catch::toString( arg ) ) \
4380+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
4381+ .setOp( "matches" ) \
4382+ .setResultType( (matcher).match( arg ) ); \
4383+ __catchResult.captureExpression(); \
4384+ } catch( ... ) { \
4385+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
4386+ } \
4387+ INTERNAL_CATCH_REACT( __catchResult ) \
4388+ } while( Catch::alwaysFalse() )
4389+
4390+// #included from: internal/catch_section.h
4391+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
4392+
4393+// #included from: catch_section_info.h
4394+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
4395+
4396+// #included from: catch_totals.hpp
4397+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
4398+
4399+#include <cstddef>
4400+
4401+namespace Catch {
4402+
4403+ struct Counts {
4404+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
4405+
4406+ Counts operator - ( Counts const& other ) const {
4407+ Counts diff;
4408+ diff.passed = passed - other.passed;
4409+ diff.failed = failed - other.failed;
4410+ diff.failedButOk = failedButOk - other.failedButOk;
4411+ return diff;
4412+ }
4413+ Counts& operator += ( Counts const& other ) {
4414+ passed += other.passed;
4415+ failed += other.failed;
4416+ failedButOk += other.failedButOk;
4417+ return *this;
4418+ }
4419+
4420+ std::size_t total() const {
4421+ return passed + failed + failedButOk;
4422+ }
4423+ bool allPassed() const {
4424+ return failed == 0 && failedButOk == 0;
4425+ }
4426+ bool allOk() const {
4427+ return failed == 0;
4428+ }
4429+
4430+ std::size_t passed;
4431+ std::size_t failed;
4432+ std::size_t failedButOk;
4433+ };
4434+
4435+ struct Totals {
4436+
4437+ Totals operator - ( Totals const& other ) const {
4438+ Totals diff;
4439+ diff.assertions = assertions - other.assertions;
4440+ diff.testCases = testCases - other.testCases;
4441+ return diff;
4442+ }
4443+
4444+ Totals delta( Totals const& prevTotals ) const {
4445+ Totals diff = *this - prevTotals;
4446+ if( diff.assertions.failed > 0 )
4447+ ++diff.testCases.failed;
4448+ else if( diff.assertions.failedButOk > 0 )
4449+ ++diff.testCases.failedButOk;
4450+ else
4451+ ++diff.testCases.passed;
4452+ return diff;
4453+ }
4454+
4455+ Totals& operator += ( Totals const& other ) {
4456+ assertions += other.assertions;
4457+ testCases += other.testCases;
4458+ return *this;
4459+ }
4460+
4461+ Counts assertions;
4462+ Counts testCases;
4463+ };
4464+}
4465+
4466+namespace Catch {
4467+
4468+ struct SectionInfo {
4469+ SectionInfo
4470+ ( SourceLineInfo const& _lineInfo,
4471+ std::string const& _name,
4472+ std::string const& _description = std::string() );
4473+
4474+ std::string name;
4475+ std::string description;
4476+ SourceLineInfo lineInfo;
4477+ };
4478+
4479+ struct SectionEndInfo {
4480+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
4481+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
4482+ {}
4483+
4484+ SectionInfo sectionInfo;
4485+ Counts prevAssertions;
4486+ double durationInSeconds;
4487+ };
4488+
4489+} // end namespace Catch
4490+
4491+// #included from: catch_timer.h
4492+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
4493+
4494+#ifdef CATCH_PLATFORM_WINDOWS
4495+typedef unsigned long long uint64_t;
4496+#else
4497+#include <stdint.h>
4498+#endif
4499+
4500+namespace Catch {
4501+
4502+ class Timer {
4503+ public:
4504+ Timer() : m_ticks( 0 ) {}
4505+ void start();
4506+ unsigned int getElapsedMicroseconds() const;
4507+ unsigned int getElapsedMilliseconds() const;
4508+ double getElapsedSeconds() const;
4509+
4510+ private:
4511+ uint64_t m_ticks;
4512+ };
4513+
4514+} // namespace Catch
4515+
4516+#include <string>
4517+
4518+namespace Catch {
4519+
4520+ class Section : NonCopyable {
4521+ public:
4522+ Section( SectionInfo const& info );
4523+ ~Section();
4524+
4525+ // This indicates whether the section should be executed or not
4526+ operator bool() const;
4527+
4528+ private:
4529+ SectionInfo m_info;
4530+
4531+ std::string m_name;
4532+ Counts m_assertions;
4533+ bool m_sectionIncluded;
4534+ Timer m_timer;
4535+ };
4536+
4537+} // end namespace Catch
4538+
4539+#ifdef CATCH_CONFIG_VARIADIC_MACROS
4540+ #define INTERNAL_CATCH_SECTION( ... ) \
4541+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
4542+#else
4543+ #define INTERNAL_CATCH_SECTION( name, desc ) \
4544+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
4545+#endif
4546+
4547+// #included from: internal/catch_generators.hpp
4548+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
4549+
4550+#include <iterator>
4551+#include <vector>
4552+#include <string>
4553+#include <stdlib.h>
4554+
4555+namespace Catch {
4556+
4557+template<typename T>
4558+struct IGenerator {
4559+ virtual ~IGenerator() {}
4560+ virtual T getValue( std::size_t index ) const = 0;
4561+ virtual std::size_t size () const = 0;
4562+};
4563+
4564+template<typename T>
4565+class BetweenGenerator : public IGenerator<T> {
4566+public:
4567+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
4568+
4569+ virtual T getValue( std::size_t index ) const {
4570+ return m_from+static_cast<int>( index );
4571+ }
4572+
4573+ virtual std::size_t size() const {
4574+ return static_cast<std::size_t>( 1+m_to-m_from );
4575+ }
4576+
4577+private:
4578+
4579+ T m_from;
4580+ T m_to;
4581+};
4582+
4583+template<typename T>
4584+class ValuesGenerator : public IGenerator<T> {
4585+public:
4586+ ValuesGenerator(){}
4587+
4588+ void add( T value ) {
4589+ m_values.push_back( value );
4590+ }
4591+
4592+ virtual T getValue( std::size_t index ) const {
4593+ return m_values[index];
4594+ }
4595+
4596+ virtual std::size_t size() const {
4597+ return m_values.size();
4598+ }
4599+
4600+private:
4601+ std::vector<T> m_values;
4602+};
4603+
4604+template<typename T>
4605+class CompositeGenerator {
4606+public:
4607+ CompositeGenerator() : m_totalSize( 0 ) {}
4608+
4609+ // *** Move semantics, similar to auto_ptr ***
4610+ CompositeGenerator( CompositeGenerator& other )
4611+ : m_fileInfo( other.m_fileInfo ),
4612+ m_totalSize( 0 )
4613+ {
4614+ move( other );
4615+ }
4616+
4617+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
4618+ m_fileInfo = fileInfo;
4619+ return *this;
4620+ }
4621+
4622+ ~CompositeGenerator() {
4623+ deleteAll( m_composed );
4624+ }
4625+
4626+ operator T () const {
4627+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
4628+
4629+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
4630+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
4631+ for( size_t index = 0; it != itEnd; ++it )
4632+ {
4633+ const IGenerator<T>* generator = *it;
4634+ if( overallIndex >= index && overallIndex < index + generator->size() )
4635+ {
4636+ return generator->getValue( overallIndex-index );
4637+ }
4638+ index += generator->size();
4639+ }
4640+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
4641+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
4642+ }
4643+
4644+ void add( const IGenerator<T>* generator ) {
4645+ m_totalSize += generator->size();
4646+ m_composed.push_back( generator );
4647+ }
4648+
4649+ CompositeGenerator& then( CompositeGenerator& other ) {
4650+ move( other );
4651+ return *this;
4652+ }
4653+
4654+ CompositeGenerator& then( T value ) {
4655+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
4656+ valuesGen->add( value );
4657+ add( valuesGen );
4658+ return *this;
4659+ }
4660+
4661+private:
4662+
4663+ void move( CompositeGenerator& other ) {
4664+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
4665+ m_totalSize += other.m_totalSize;
4666+ other.m_composed.clear();
4667+ }
4668+
4669+ std::vector<const IGenerator<T>*> m_composed;
4670+ std::string m_fileInfo;
4671+ size_t m_totalSize;
4672+};
4673+
4674+namespace Generators
4675+{
4676+ template<typename T>
4677+ CompositeGenerator<T> between( T from, T to ) {
4678+ CompositeGenerator<T> generators;
4679+ generators.add( new BetweenGenerator<T>( from, to ) );
4680+ return generators;
4681+ }
4682+
4683+ template<typename T>
4684+ CompositeGenerator<T> values( T val1, T val2 ) {
4685+ CompositeGenerator<T> generators;
4686+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
4687+ valuesGen->add( val1 );
4688+ valuesGen->add( val2 );
4689+ generators.add( valuesGen );
4690+ return generators;
4691+ }
4692+
4693+ template<typename T>
4694+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
4695+ CompositeGenerator<T> generators;
4696+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
4697+ valuesGen->add( val1 );
4698+ valuesGen->add( val2 );
4699+ valuesGen->add( val3 );
4700+ generators.add( valuesGen );
4701+ return generators;
4702+ }
4703+
4704+ template<typename T>
4705+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
4706+ CompositeGenerator<T> generators;
4707+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
4708+ valuesGen->add( val1 );
4709+ valuesGen->add( val2 );
4710+ valuesGen->add( val3 );
4711+ valuesGen->add( val4 );
4712+ generators.add( valuesGen );
4713+ return generators;
4714+ }
4715+
4716+} // end namespace Generators
4717+
4718+using namespace Generators;
4719+
4720+} // end namespace Catch
4721+
4722+#define INTERNAL_CATCH_LINESTR2( line ) #line
4723+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
4724+
4725+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
4726+
4727+// #included from: internal/catch_interfaces_exception.h
4728+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
4729+
4730+#include <string>
4731+#include <vector>
4732+
4733+// #included from: catch_interfaces_registry_hub.h
4734+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
4735+
4736+#include <string>
4737+
4738+namespace Catch {
4739+
4740+ class TestCase;
4741+ struct ITestCaseRegistry;
4742+ struct IExceptionTranslatorRegistry;
4743+ struct IExceptionTranslator;
4744+ struct IReporterRegistry;
4745+ struct IReporterFactory;
4746+
4747+ struct IRegistryHub {
4748+ virtual ~IRegistryHub();
4749+
4750+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
4751+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
4752+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
4753+ };
4754+
4755+ struct IMutableRegistryHub {
4756+ virtual ~IMutableRegistryHub();
4757+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
4758+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
4759+ virtual void registerTest( TestCase const& testInfo ) = 0;
4760+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
4761+ };
4762+
4763+ IRegistryHub& getRegistryHub();
4764+ IMutableRegistryHub& getMutableRegistryHub();
4765+ void cleanUp();
4766+ std::string translateActiveException();
4767+
4768+}
4769+
4770+namespace Catch {
4771+
4772+ typedef std::string(*exceptionTranslateFunction)();
4773+
4774+ struct IExceptionTranslator;
4775+ typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
4776+
4777+ struct IExceptionTranslator {
4778+ virtual ~IExceptionTranslator();
4779+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
4780+ };
4781+
4782+ struct IExceptionTranslatorRegistry {
4783+ virtual ~IExceptionTranslatorRegistry();
4784+
4785+ virtual std::string translateActiveException() const = 0;
4786+ };
4787+
4788+ class ExceptionTranslatorRegistrar {
4789+ template<typename T>
4790+ class ExceptionTranslator : public IExceptionTranslator {
4791+ public:
4792+
4793+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
4794+ : m_translateFunction( translateFunction )
4795+ {}
4796+
4797+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
4798+ try {
4799+ if( it == itEnd )
4800+ throw;
4801+ else
4802+ return (*it)->translate( it+1, itEnd );
4803+ }
4804+ catch( T& ex ) {
4805+ return m_translateFunction( ex );
4806+ }
4807+ }
4808+
4809+ protected:
4810+ std::string(*m_translateFunction)( T& );
4811+ };
4812+
4813+ public:
4814+ template<typename T>
4815+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
4816+ getMutableRegistryHub().registerTranslator
4817+ ( new ExceptionTranslator<T>( translateFunction ) );
4818+ }
4819+ };
4820+}
4821+
4822+///////////////////////////////////////////////////////////////////////////////
4823+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
4824+ static std::string translatorName( signature ); \
4825+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
4826+ static std::string translatorName( signature )
4827+
4828+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
4829+
4830+// #included from: internal/catch_approx.hpp
4831+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
4832+
4833+#include <cmath>
4834+#include <limits>
4835+
4836+namespace Catch {
4837+namespace Detail {
4838+
4839+ class Approx {
4840+ public:
4841+ explicit Approx ( double value )
4842+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
4843+ m_scale( 1.0 ),
4844+ m_value( value )
4845+ {}
4846+
4847+ Approx( Approx const& other )
4848+ : m_epsilon( other.m_epsilon ),
4849+ m_scale( other.m_scale ),
4850+ m_value( other.m_value )
4851+ {}
4852+
4853+ static Approx custom() {
4854+ return Approx( 0 );
4855+ }
4856+
4857+ Approx operator()( double value ) {
4858+ Approx approx( value );
4859+ approx.epsilon( m_epsilon );
4860+ approx.scale( m_scale );
4861+ return approx;
4862+ }
4863+
4864+ friend bool operator == ( double lhs, Approx const& rhs ) {
4865+ // Thanks to Richard Harris for his help refining this formula
4866+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
4867+ }
4868+
4869+ friend bool operator == ( Approx const& lhs, double rhs ) {
4870+ return operator==( rhs, lhs );
4871+ }
4872+
4873+ friend bool operator != ( double lhs, Approx const& rhs ) {
4874+ return !operator==( lhs, rhs );
4875+ }
4876+
4877+ friend bool operator != ( Approx const& lhs, double rhs ) {
4878+ return !operator==( rhs, lhs );
4879+ }
4880+
4881+ Approx& epsilon( double newEpsilon ) {
4882+ m_epsilon = newEpsilon;
4883+ return *this;
4884+ }
4885+
4886+ Approx& scale( double newScale ) {
4887+ m_scale = newScale;
4888+ return *this;
4889+ }
4890+
4891+ std::string toString() const {
4892+ std::ostringstream oss;
4893+ oss << "Approx( " << Catch::toString( m_value ) << " )";
4894+ return oss.str();
4895+ }
4896+
4897+ private:
4898+ double m_epsilon;
4899+ double m_scale;
4900+ double m_value;
4901+ };
4902+}
4903+
4904+template<>
4905+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
4906+ return value.toString();
4907+}
4908+
4909+} // end namespace Catch
4910+
4911+// #included from: internal/catch_interfaces_tag_alias_registry.h
4912+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
4913+
4914+// #included from: catch_tag_alias.h
4915+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
4916+
4917+#include <string>
4918+
4919+namespace Catch {
4920+
4921+ struct TagAlias {
4922+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
4923+
4924+ std::string tag;
4925+ SourceLineInfo lineInfo;
4926+ };
4927+
4928+ struct RegistrarForTagAliases {
4929+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
4930+ };
4931+
4932+} // end namespace Catch
4933+
4934+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
4935+// #included from: catch_option.hpp
4936+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
4937+
4938+namespace Catch {
4939+
4940+ // An optional type
4941+ template<typename T>
4942+ class Option {
4943+ public:
4944+ Option() : nullableValue( CATCH_NULL ) {}
4945+ Option( T const& _value )
4946+ : nullableValue( new( storage ) T( _value ) )
4947+ {}
4948+ Option( Option const& _other )
4949+ : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
4950+ {}
4951+
4952+ ~Option() {
4953+ reset();
4954+ }
4955+
4956+ Option& operator= ( Option const& _other ) {
4957+ if( &_other != this ) {
4958+ reset();
4959+ if( _other )
4960+ nullableValue = new( storage ) T( *_other );
4961+ }
4962+ return *this;
4963+ }
4964+ Option& operator = ( T const& _value ) {
4965+ reset();
4966+ nullableValue = new( storage ) T( _value );
4967+ return *this;
4968+ }
4969+
4970+ void reset() {
4971+ if( nullableValue )
4972+ nullableValue->~T();
4973+ nullableValue = CATCH_NULL;
4974+ }
4975+
4976+ T& operator*() { return *nullableValue; }
4977+ T const& operator*() const { return *nullableValue; }
4978+ T* operator->() { return nullableValue; }
4979+ const T* operator->() const { return nullableValue; }
4980+
4981+ T valueOr( T const& defaultValue ) const {
4982+ return nullableValue ? *nullableValue : defaultValue;
4983+ }
4984+
4985+ bool some() const { return nullableValue != CATCH_NULL; }
4986+ bool none() const { return nullableValue == CATCH_NULL; }
4987+
4988+ bool operator !() const { return nullableValue == CATCH_NULL; }
4989+ operator SafeBool::type() const {
4990+ return SafeBool::makeSafe( some() );
4991+ }
4992+
4993+ private:
4994+ T* nullableValue;
4995+ char storage[sizeof(T)];
4996+ };
4997+
4998+} // end namespace Catch
4999+
5000+namespace Catch {
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches