26 #ifndef QUICKCHECK_PROPERTY_H
27 #define QUICKCHECK_PROPERTY_H
39 namespace quickcheck {
62 out <<
" " << n <<
": " << a << std::endl;
84 template<
class A,
class B,
class C,
class D,
class E>
110 bool check(
size_t n = 100,
size_t max = 0,
bool isVerbose =
false,
111 std::ostream& out = std::cout);
126 void _addFixed(
const A& a,
const B& b,
const C& c,
const D& d,
153 void printInput(std::ostream& out,
const A& a,
const B& b,
const C& c,
154 const D& d,
const E& e);
163 virtual size_t sizeHint(
size_t testNo);
176 virtual bool _accepts(
const A& a,
const B& b,
const C& c,
const D& d,
190 virtual const std::string
_classify(
const A& a,
const B& b,
const C& c,
191 const D& d,
const E& e) = 0;
203 virtual void _generateInput(
size_t n, A& a, B& b, C& c, D& d, E& e) = 0;
216 virtual bool _holdsFor(
const A& a,
const B& b,
const C& c,
const D& d,
231 virtual bool _isTrivialFor(
const A& a,
const B& b,
const C& c,
232 const D& d,
const E& e) = 0;
242 template<
class A,
class B,
class C,
class D,
class E>
244 _fixedInputs(std::vector<
Input>())
249 template<
class A,
class B,
class C,
class D,
class E>
255 template<
class A,
class B,
class C,
class D,
class E>
264 typedef std::map<const std::string, size_t> ClassMap;
267 size_t len = _fixedInputs.size();
269 for (testNo = 0; testNo < len; ++testNo) {
270 const Input& input = _fixedInputs[testNo];
271 if (_isTrivialFor(input.
a, input.
b, input.
c, input.
d, input.
e))
273 ++classes[_classify(input.
a, input.
b, input.
c, input.
d, input.
e)];
275 out <<
"Test " << testNo <<
":" << std::endl;
276 printInput(out, input.
a, input.
b, input.
c, input.
d, input.
e);
278 if (!_holdsFor(input.
a, input.
b, input.
c, input.
d, input.
e)) {
279 out <<
"Falsifiable after " << testNo + 1 <<
" tests for input:" <<
281 printInput(out, input.
a, input.
b, input.
c, input.
d, input.
e);
288 for (attemptNo = 0; attemptNo < max && testNo < n; ++attemptNo) {
297 _generateInput(sizeHint(testNo - len), a, b, c, d, e);
299 if (_accepts(a, b, c, d, e)) {
300 if (_isTrivialFor(a, b, c, d, e))
302 ++classes[_classify(a, b, c, d, e)];
304 out <<
"Test " << testNo <<
":" << std::endl;
305 printInput(out, a, b, c, d, e);
307 if (!_holdsFor(a, b, c, d, e)) {
308 out <<
"Falsifiable after " << testNo + 1 <<
" tests for input:"
310 printInput(out, a, b, c, d, e);
318 out <<
"Arguments exhausted after ";
320 out <<
"OK, passed ";
321 out << testNo <<
" tests";
323 out <<
" (" << nTrivial * 100 / testNo <<
"% trivial)";
324 out <<
"." << std::endl;
327 if (!classes.empty()) {
330 typedef std::vector< std::pair<size_t, std::string> > ClassVec;
332 for (ClassMap::const_iterator i = classes.begin(); i != classes.end();
334 std::pair<size_t, std::string> elem = make_pair(i->second, i->first);
335 ClassVec::iterator pos = lower_bound(sorted.begin(), sorted.end(),
337 sorted.insert(pos, elem);
339 std::reverse(sorted.begin(), sorted.end());
340 for (ClassVec::const_iterator i = sorted.begin(); i != sorted.end(); ++i)
341 out << std::setw(4) << i->first * 100 / testNo <<
"% " << i->second
344 return (testNo == n);
347 template<
class A,
class B,
class C,
class D,
class E>
349 const D& d,
const E& e)
351 Input i = { a, b, c, d, e };
352 _fixedInputs.push_back(i);
355 template<
class A,
class B,
class C,
class D,
class E>
357 const B& b,
const C& c,
358 const D& d,
const E& e)
369 template<
class A,
class B,
class C,
class D,
class E>
372 return testNo / 2 + 3;
402 template<
class A,
class B =
Unit,
class C =
Unit,
class D =
Unit,
417 virtual void addFixed(
const A& a,
const B& b,
const C& c,
const D& d,
448 virtual bool accepts(
const A& a,
const B& b,
const C& c,
const D& d,
466 virtual const std::string
classify(
const A& a,
const B& b,
const C& c,
467 const D& d,
const E& e);
493 virtual void generateInput(
size_t n, A& a, B& b, C& c, D& d, E& e);
511 virtual bool holdsFor(
const A& a,
const B& b,
const C& c,
const D& d,
531 virtual bool isTrivialFor(
const A& a,
const B& b,
const C& c,
const D& d,
534 bool _accepts(
const A& a,
const B& b,
const C& c,
const D& d,
537 const std::string
_classify(
const A& a,
const B& b,
const C& c,
538 const D& d,
const E& e);
542 bool _holdsFor(
const A& a,
const B& b,
const C& c,
const D& d,
545 bool _isTrivialFor(
const A& a,
const B& b,
const C& c,
const D& d,
550 template<
class A,
class B,
class C,
class D,
class E>
552 const D& d,
const E& e)
554 this->_addFixed(a, b, c, d, e);
557 template<
class A,
class B,
class C,
class D,
class E>
564 template<
class A,
class B,
class C,
class D,
class E>
566 const A&,
const B&,
const C&,
const D&,
const E&)
571 template<
class A,
class B,
class C,
class D,
class E>
573 A& a, B& b, C& c, D& d, E& e)
582 template<
class A,
class B,
class C,
class D,
class E>
589 template<
class A,
class B,
class C,
class D,
class E>
591 const D& d,
const E& e)
593 return accepts(a, b, c, d, e);
596 template<
class A,
class B,
class C,
class D,
class E>
598 const A& a,
const B& b,
const C& c,
const D& d,
const E& e)
600 return classify(a, b, c, d, e);
603 template<
class A,
class B,
class C,
class D,
class E>
605 A& a, B& b, C& c, D& d, E& e)
607 generateInput(n, a, b, c, d, e);
610 template<
class A,
class B,
class C,
class D,
class E>
612 const D& d,
const E& e)
614 return holdsFor(a, b, c, d, e);
617 template<
class A,
class B,
class C,
class D,
class E>
619 const D& d,
const E& e)
621 return isTrivialFor(a, b, c, d, e);
633 template<
class A,
class B,
class C,
class D>
648 virtual void addFixed(
const A& a,
const B& b,
const C& c,
const D& d);
662 virtual bool accepts(
const A& a,
const B& b,
const C& c,
const D& d);
674 virtual const std::string
classify(
const A& a,
const B& b,
const C& c,
688 virtual void generateInput(
size_t n, A& a, B& b, C& c, D& d);
700 virtual bool holdsFor(
const A& a,
const B& b,
const C& c,
const D& d)
713 virtual bool isTrivialFor(
const A& a,
const B& b,
const C& c,
716 bool _accepts(
const A& a,
const B& b,
const C& c,
const D& d,
719 const std::string
_classify(
const A& a,
const B& b,
const C& c,
720 const D& d,
const Unit& e);
724 bool _holdsFor(
const A& a,
const B& b,
const C& c,
const D& d,
727 bool _isTrivialFor(
const A& a,
const B& b,
const C& c,
const D& d,
732 template<
class A,
class B,
class C,
class D>
739 template<
class A,
class B,
class C,
class D>
745 template<
class A,
class B,
class C,
class D>
752 template<
class A,
class B,
class C,
class D>
761 template<
class A,
class B,
class C,
class D>
768 template<
class A,
class B,
class C,
class D>
770 const D& d,
const Unit&)
775 template<
class A,
class B,
class C,
class D>
777 const A& a,
const B& b,
const C& c,
const D& d,
const Unit&)
782 template<
class A,
class B,
class C,
class D>
789 template<
class A,
class B,
class C,
class D>
791 const D& d,
const Unit&)
796 template<
class A,
class B,
class C,
class D>
798 const D& d,
const Unit&)
811 template<
class A,
class B,
class C>
825 virtual void addFixed(
const A& a,
const B& b,
const C& c);
838 virtual bool accepts(
const A& a,
const B& b,
const C& c);
849 virtual const std::string
classify(
const A& a,
const B& b,
const C& c);
872 virtual bool holdsFor(
const A& a,
const B& b,
const C& c) = 0;
883 virtual bool isTrivialFor(
const A& a,
const B& b,
const C& c);
885 bool _accepts(
const A& a,
const B& b,
const C& c,
const Unit& d,
888 const std::string
_classify(
const A& a,
const B& b,
const C& c,
893 bool _holdsFor(
const A& a,
const B& b,
const C& c,
const Unit& d,
901 template<
class A,
class B,
class C>
907 template<
class A,
class B,
class C>
913 template<
class A,
class B,
class C>
919 template<
class A,
class B,
class C>
927 template<
class A,
class B,
class C>
933 template<
class A,
class B,
class C>
940 template<
class A,
class B,
class C>
942 const A& a,
const B& b,
const C& c,
const Unit&,
const Unit&)
947 template<
class A,
class B,
class C>
954 template<
class A,
class B,
class C>
961 template<
class A,
class B,
class C>
975 template<
class A,
class B>
988 virtual void addFixed(
const A& a,
const B& b);
1000 virtual bool accepts(
const A& a,
const B& b);
1010 virtual const std::string
classify(
const A& a,
const B& b);
1031 virtual bool holdsFor(
const A& a,
const B& b) = 0;
1046 const std::string
_classify(
const A& a,
const B& b,
const Unit& c,
1059 template<
class A,
class B>
1065 template<
class A,
class B>
1071 template<
class A,
class B>
1077 template<
class A,
class B>
1084 template<
class A,
class B>
1090 template<
class A,
class B>
1097 template<
class A,
class B>
1099 const A& a,
const B& b,
const Unit&,
const Unit&,
const Unit&)
1104 template<
class A,
class B>
1110 template<
class A,
class B>
1117 template<
class A,
class B>
1153 virtual bool accepts(
const A& a);
1162 virtual const std::string
classify(
const A& a);
1181 virtual bool holdsFor(
const A& a) = 0;
1274 #endif // !QUICKCHECK_PROPERTY_H