test_non_intrusive.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_non_intrursive.cpp
  3. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  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. // should pass compilation and execution
  8. // this tests:
  9. // a) non-intrusive method of implementing serialization
  10. // b) usage of a non-default constructor
  11. #include <fstream>
  12. #include <cstdlib> // for rand()
  13. #include <cstdio> // remove
  14. #include <boost/config.hpp>
  15. #include <boost/detail/workaround.hpp>
  16. #include <boost/limits.hpp>
  17. #include <boost/math/special_functions/next.hpp>
  18. #if defined(BOOST_NO_STDC_NAMESPACE)
  19. namespace std{
  20. using ::rand;
  21. using ::remove;
  22. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
  23. using ::numeric_limits;
  24. #endif
  25. }
  26. #endif
  27. #include <boost/archive/archive_exception.hpp>
  28. #include "test_tools.hpp"
  29. ///////////////////////////////////////////////////////
  30. // simple class test - using non-intrusive syntax
  31. // illustrates the usage of the non-intrusve syntax
  32. class A
  33. {
  34. public:
  35. signed char s;
  36. unsigned char t;
  37. signed int u;
  38. unsigned int v;
  39. float w;
  40. double x;
  41. A();
  42. bool operator==(const A & rhs) const;
  43. bool operator<(const A & rhs) const;
  44. };
  45. A::A() :
  46. s(static_cast<signed char>(0xff & std::rand())),
  47. t(static_cast<signed char>(0xff & std::rand())),
  48. u(std::rand()),
  49. v(std::rand()),
  50. w((float)std::rand() / std::rand()),
  51. x((double)std::rand() / std::rand())
  52. {
  53. }
  54. bool A::operator==(const A &rhs) const
  55. {
  56. return
  57. s == rhs.s
  58. && t == rhs.t
  59. && u == rhs.u
  60. && v == rhs.v
  61. && std::abs( boost::math::float_distance(w, rhs.w)) < 2
  62. && std::abs( boost::math::float_distance(x, rhs.x)) < 2
  63. ;
  64. }
  65. bool A::operator<(const A &rhs) const
  66. {
  67. if(! (s == rhs.s) )
  68. return s < rhs.s;
  69. if(! (t == rhs.t) )
  70. return t < rhs.t;
  71. if(! (u == rhs.u) )
  72. return t < rhs.u;
  73. if(! (v == rhs.v) )
  74. return t < rhs.v;
  75. if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
  76. return false;
  77. if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
  78. return false;
  79. return false;
  80. }
  81. // note the following:
  82. // function specializations must be defined in the appropriate
  83. // namespace - boost::serialization
  84. namespace boost {
  85. namespace serialization {
  86. // This first set of overrides should work with all compilers.
  87. // The last argument is int while the default versions
  88. // defined in serialization.hpp have long as the last argument.
  89. // This is part of the work around for compilers that don't
  90. // support correct function template ordering. These functions
  91. // are always called with 0 (i.e. an int) as the last argument.
  92. // Our specialized versions also have int as the last argument
  93. // while the default versions have a long as the last argument.
  94. // This makes our specialized versions a better match than the
  95. // default ones as no argument conversion is required to make a match
  96. template<class Archive>
  97. void serialize(
  98. Archive & ar,
  99. A & a,
  100. const unsigned int /* file_version */
  101. ){
  102. ar & boost::serialization::make_nvp("s", a.s);
  103. ar & boost::serialization::make_nvp("t", a.t);
  104. ar & boost::serialization::make_nvp("u", a.u);
  105. ar & boost::serialization::make_nvp("v", a.v);
  106. ar & boost::serialization::make_nvp("w", a.w);
  107. ar & boost::serialization::make_nvp("x", a.x);
  108. }
  109. } // serialization
  110. } // namespace boost
  111. void save(const char * testfile){
  112. test_ostream os(testfile, TEST_STREAM_FLAGS);
  113. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  114. A a;
  115. oa << BOOST_SERIALIZATION_NVP(a);
  116. // save a copy pointer to this item
  117. A *pa1 = &a;
  118. oa << BOOST_SERIALIZATION_NVP(pa1);
  119. // save pointer to a new object
  120. A *pa2 = new A();
  121. oa << BOOST_SERIALIZATION_NVP(pa2);
  122. delete pa2;
  123. }
  124. void load(const char * testfile){
  125. test_istream is(testfile, TEST_STREAM_FLAGS);
  126. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  127. A a;
  128. ia >> BOOST_SERIALIZATION_NVP(a);
  129. A *pa1;
  130. ia >> BOOST_SERIALIZATION_NVP(pa1);
  131. BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
  132. A *pa2;
  133. ia >> BOOST_SERIALIZATION_NVP(pa2);
  134. BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
  135. delete pa2;
  136. }
  137. int
  138. test_main( int /* argc */, char* /* argv */[] )
  139. {
  140. const char * testfile = boost::archive::tmpnam(NULL);
  141. BOOST_REQUIRE(NULL != testfile);
  142. save(testfile);
  143. load(testfile);
  144. std::remove(testfile);
  145. return EXIT_SUCCESS;
  146. }
  147. // EOF