file_iterator_tests.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*=============================================================================
  2. Copyright (c) 2003 Giovanni Bajo
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #include <boost/detail/lightweight_test.hpp>
  9. #include <cstdio>
  10. #include <iostream>
  11. #include <boost/concept_check.hpp>
  12. #include <boost/spirit/include/classic_file_iterator.hpp>
  13. // This checks for a namespace related problem in VC8
  14. // The problem can be avoided by not using "using namespace std;" in the
  15. // Spirit headers
  16. namespace vc8_bug_1 { struct plus {}; }
  17. namespace vc8_bug_2 { using namespace vc8_bug_1; struct test : plus {}; }
  18. using namespace std;
  19. using namespace BOOST_SPIRIT_CLASSIC_NS;
  20. namespace {
  21. static const char* TMP_FILE = "file_iter.tmp";
  22. bool CreateTempFile(void)
  23. {
  24. FILE* f = fopen(TMP_FILE, "wb");
  25. if (!f)
  26. return false;
  27. for (int i=0;i<256;i++)
  28. {
  29. unsigned char ci = (unsigned char)i;
  30. if (fwrite(&ci,1,1,f) == 0)
  31. {
  32. fclose(f);
  33. return false;
  34. }
  35. }
  36. fclose(f);
  37. return true;
  38. }
  39. template <typename ITER>
  40. void RunTest(void)
  41. {
  42. // Check constructor opening a file
  43. ITER a(TMP_FILE);
  44. BOOST_TEST(!!a);
  45. // Assert dereference (twice: derefence
  46. // must not move the iterator)
  47. BOOST_TEST(*a == 0);
  48. BOOST_TEST(*a == 0);
  49. // Check random access
  50. BOOST_TEST(a[123] == 123);
  51. // Check copy constructor and operator==
  52. ITER c(a);
  53. BOOST_TEST(c == a);
  54. BOOST_TEST(!(c != a));
  55. // Check assignment operator
  56. ITER d; d = a;
  57. BOOST_TEST(d == a);
  58. BOOST_TEST(!(d != a));
  59. // Check make_end()
  60. ITER b(a.make_end());
  61. BOOST_TEST(!!b);
  62. BOOST_TEST(a != b);
  63. BOOST_TEST(a+256 == b);
  64. BOOST_TEST(a == b-256);
  65. // Check copy constructor on non-trivial position
  66. BOOST_TEST(*ITER(a+67) == 67);
  67. // Check increment
  68. ++a; ++a; a++; a++;
  69. BOOST_TEST(*a == 4);
  70. BOOST_TEST(a == c+4);
  71. // Check decrement
  72. --a; --a; a--; a--;
  73. BOOST_TEST(*a == 0);
  74. BOOST_TEST(a == c);
  75. // Check end iterator increment/decrement
  76. --b; b--;
  77. BOOST_TEST(*b == 254);
  78. BOOST_TEST(a+254 == b);
  79. ++b; b++;
  80. BOOST_TEST(a+256 == b);
  81. // Check order
  82. a += 128;
  83. BOOST_TEST(c < a);
  84. BOOST_TEST(a < b);
  85. BOOST_TEST(a > c);
  86. BOOST_TEST(b > a);
  87. // Check assignment
  88. a = b;
  89. BOOST_TEST(a == b);
  90. a = c;
  91. BOOST_TEST(a == c);
  92. // Check weak order
  93. BOOST_TEST(a <= c);
  94. BOOST_TEST(a >= c);
  95. BOOST_TEST(a <= b);
  96. BOOST_TEST(!(a >= b));
  97. // Check increment through end
  98. a += 255;
  99. BOOST_TEST(a != b);
  100. ++a;
  101. BOOST_TEST(a == b);
  102. ++a;
  103. BOOST_TEST(a != b);
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. }
  107. typedef unsigned char character_t;
  108. typedef file_iterator<character_t,
  109. fileiter_impl::std_file_iterator<character_t> > iter;
  110. BOOST_CLASS_REQUIRE(iter, boost, RandomAccessIteratorConcept);
  111. #ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
  112. typedef file_iterator<character_t,
  113. fileiter_impl::mmap_file_iterator<character_t> > iterwin;
  114. BOOST_CLASS_REQUIRE(iterwin, boost, RandomAccessIteratorConcept);
  115. #endif
  116. #ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
  117. typedef file_iterator<character_t,
  118. fileiter_impl::mmap_file_iterator<character_t> > iterposix;
  119. BOOST_CLASS_REQUIRE(iterposix, boost, RandomAccessIteratorConcept);
  120. #endif
  121. int main(void)
  122. {
  123. if (!CreateTempFile())
  124. {
  125. cerr << "ERROR: Cannot create temporary file file_iter.tmp" << endl;
  126. return 2;
  127. }
  128. cerr << "Testing standard iterator" << endl;
  129. RunTest<iter>();
  130. #ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
  131. cerr << "Testing Windows iterator" << endl;
  132. RunTest<iterwin>();
  133. #endif
  134. #ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
  135. cerr << "Testing POSIX iterator" << endl;
  136. RunTest<iterposix>();
  137. #endif
  138. // Check if the file handles were closed correctly
  139. BOOST_TEST(remove(TMP_FILE) == 0);
  140. return boost::report_errors();
  141. }
  142. #ifdef BOOST_NO_EXCEPTIONS
  143. namespace boost {
  144. void throw_exception(std::exception const& e)
  145. {
  146. BOOST_EROR("throw_exception");
  147. }
  148. }
  149. #endif