test_non_default_ctor.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_non_default_ctor.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 <cstddef> // NULL
  12. #include <cstdio> // remove()
  13. #include <fstream>
  14. #include <cstdlib> // for rand()
  15. #include <boost/config.hpp>
  16. #include <boost/detail/workaround.hpp>
  17. #include <boost/limits.hpp>
  18. #include <boost/math/special_functions/next.hpp>
  19. #if defined(BOOST_NO_STDC_NAMESPACE)
  20. namespace std{
  21. using ::rand;
  22. using ::remove;
  23. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
  24. using ::numeric_limits;
  25. #endif
  26. }
  27. #endif
  28. #include <boost/archive/archive_exception.hpp>
  29. #include "test_tools.hpp"
  30. ///////////////////////////////////////////////////////
  31. // simple class test - using non-intrusive syntax
  32. // illustrates the usage of the non-intrusve syntax
  33. class A
  34. {
  35. friend class boost::serialization::access;
  36. // note const values can only be initialized with a non
  37. // non-default constructor
  38. const int i;
  39. signed char s;
  40. unsigned char t;
  41. signed int u;
  42. unsigned int v;
  43. float w;
  44. double x;
  45. bool operator==(const A & rhs) const;
  46. bool operator<(const A & rhs) const;
  47. template<class Archive>
  48. void serialize(Archive & ar,const unsigned int /* file_version */){
  49. ar & BOOST_SERIALIZATION_NVP(s);
  50. ar & BOOST_SERIALIZATION_NVP(t);
  51. ar & BOOST_SERIALIZATION_NVP(u);
  52. ar & BOOST_SERIALIZATION_NVP(v);
  53. ar & BOOST_SERIALIZATION_NVP(w);
  54. ar & BOOST_SERIALIZATION_NVP(x);
  55. }
  56. A(const A & rhs);
  57. A & operator=(const A & rhs);
  58. public:
  59. static int count;
  60. const int & get_i() const {
  61. return i;
  62. }
  63. A(int i_);
  64. ~A();
  65. };
  66. int A::count = 0;
  67. A::A(int i_) :
  68. i(i_),
  69. s(static_cast<signed char>(0xff & std::rand())),
  70. t(static_cast<signed char>(0xff & std::rand())),
  71. u(std::rand()),
  72. v(std::rand()),
  73. w((float)std::rand() / std::rand()),
  74. x((double)std::rand() / std::rand())
  75. {
  76. ++count;
  77. }
  78. A::~A(){
  79. --count;
  80. }
  81. bool A::operator==(const A &rhs) const
  82. {
  83. return
  84. s == rhs.s
  85. && t == rhs.t
  86. && u == rhs.u
  87. && v == rhs.v
  88. && std::abs( boost::math::float_distance(w, rhs.w)) < 2
  89. && std::abs( boost::math::float_distance(x, rhs.x)) < 2
  90. ;
  91. }
  92. bool A::operator<(const A &rhs) const
  93. {
  94. if(! (s == rhs.s) )
  95. return s < rhs.s;
  96. if(! (t == rhs.t) )
  97. return t < rhs.t;
  98. if(! (u == rhs.u) )
  99. return t < rhs.u;
  100. if(! (v == rhs.v) )
  101. return t < rhs.v;
  102. if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
  103. return false;
  104. if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
  105. return false;
  106. return false;
  107. }
  108. namespace boost {
  109. namespace serialization {
  110. template<class Archive>
  111. inline void save_construct_data(
  112. Archive & ar,
  113. const A * a,
  114. const unsigned int /* file_version */
  115. ){
  116. // variable used for construction
  117. ar << boost::serialization::make_nvp("i", a->get_i());
  118. }
  119. template<class Archive>
  120. inline void load_construct_data(
  121. Archive & ar,
  122. A * a,
  123. const unsigned int /* file_version */
  124. ){
  125. int i;
  126. ar >> boost::serialization::make_nvp("i", i);
  127. ::new(a)A(i);
  128. }
  129. } // serialization
  130. } // namespace boost
  131. void save(const char * testfile){
  132. test_ostream os(testfile, TEST_STREAM_FLAGS);
  133. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  134. A a(2);
  135. oa << BOOST_SERIALIZATION_NVP(a);
  136. // save a copy pointer to this item
  137. A *pa1 = &a;
  138. oa << BOOST_SERIALIZATION_NVP(pa1);
  139. // save pointer to a new object
  140. A *pa2 = new A(4);
  141. oa << BOOST_SERIALIZATION_NVP(pa2);
  142. delete pa2;
  143. }
  144. void load(const char * testfile){
  145. test_istream is(testfile, TEST_STREAM_FLAGS);
  146. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  147. A a(4);
  148. ia >> BOOST_SERIALIZATION_NVP(a);
  149. A *pa1;
  150. ia >> BOOST_SERIALIZATION_NVP(pa1);
  151. BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
  152. A *pa2;
  153. ia >> BOOST_SERIALIZATION_NVP(pa2);
  154. BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
  155. delete pa2;
  156. }
  157. int
  158. test_main( int /* argc */, char* /* argv */[] )
  159. {
  160. const char * testfile = boost::archive::tmpnam(NULL);
  161. BOOST_REQUIRE(NULL != testfile);
  162. save(testfile);
  163. load(testfile);
  164. BOOST_CHECK(0 == A::count);
  165. std::remove(testfile);
  166. return EXIT_SUCCESS;
  167. }
  168. // EOF