test_new_operator.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_new_operator.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. #include <cstddef> // NULL
  9. #include <cstdio> // remove
  10. #include <fstream>
  11. #include <new>
  12. #include <boost/config.hpp>
  13. #if defined(BOOST_NO_STDC_NAMESPACE)
  14. namespace std{
  15. using ::remove;
  16. }
  17. #endif
  18. #include <boost/serialization/access.hpp>
  19. #include "test_tools.hpp"
  20. #include "A.hpp"
  21. #include "A.ipp"
  22. class ANew : public A {
  23. friend class boost::serialization::access;
  24. template<class Archive>
  25. void serialize(Archive & ar, const unsigned /*file_version*/){
  26. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
  27. }
  28. public:
  29. static unsigned int m_new_calls;
  30. static unsigned int m_delete_calls;
  31. // implement class specific new/delete in terms standard
  32. // implementation - we're testing serialization
  33. // not "new" here.
  34. static void * operator new(size_t s){
  35. ++m_new_calls;
  36. return ::operator new(s);
  37. }
  38. static void operator delete(void *p, std::size_t){
  39. ++m_delete_calls;
  40. ::operator delete(p);
  41. }
  42. };
  43. unsigned int ANew::m_new_calls = 0;
  44. unsigned int ANew::m_delete_calls = 0;
  45. class ANew1 : public A {
  46. friend class boost::serialization::access;
  47. template<class Archive>
  48. void serialize(Archive & ar, const unsigned /*file_version*/){
  49. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
  50. }
  51. public:
  52. static unsigned int m_new_calls;
  53. static unsigned int m_delete_calls;
  54. // implement class specific new/delete in terms standard
  55. // implementation - we're testing serialization
  56. // not "new" here.
  57. static void * operator new(size_t s){
  58. ++m_new_calls;
  59. return ::operator new(s);
  60. }
  61. static void operator delete(void *p){
  62. ++m_delete_calls;
  63. ::operator delete(p);
  64. }
  65. };
  66. unsigned int ANew1::m_new_calls = 0;
  67. unsigned int ANew1::m_delete_calls = 0;
  68. class ANew2 : public A {
  69. friend class boost::serialization::access;
  70. template<class Archive>
  71. void serialize(Archive & ar, const unsigned /*file_version*/){
  72. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
  73. }
  74. public:
  75. static unsigned int m_new_calls;
  76. static unsigned int m_delete_calls;
  77. // implement class specific new/delete in terms standard
  78. // implementation - we're testing serialization
  79. // not "new" here.
  80. static void * operator new(size_t s){
  81. ++m_new_calls;
  82. return ::operator new(s);
  83. }
  84. };
  85. unsigned int ANew2::m_new_calls = 0;
  86. unsigned int ANew2::m_delete_calls = 0;
  87. template<typename T>
  88. int test(){
  89. const char * testfile = boost::archive::tmpnam(NULL);
  90. BOOST_REQUIRE(NULL != testfile);
  91. T *ta = new T();
  92. BOOST_CHECK(1 == T::m_new_calls);
  93. BOOST_CHECK(0 == T::m_delete_calls);
  94. T *ta1 = NULL;
  95. {
  96. test_ostream os(testfile, TEST_STREAM_FLAGS);
  97. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  98. oa << boost::serialization::make_nvp("ta", ta);
  99. }
  100. {
  101. test_istream is(testfile, TEST_STREAM_FLAGS);
  102. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  103. ia >> boost::serialization::make_nvp("ta", ta1);
  104. }
  105. BOOST_CHECK(ta != ta1);
  106. BOOST_CHECK(*ta == *ta1);
  107. BOOST_CHECK(2 == T::m_new_calls);
  108. BOOST_CHECK(0 == T::m_delete_calls);
  109. std::remove(testfile);
  110. delete ta;
  111. delete ta1;
  112. BOOST_CHECK(2 == T::m_new_calls);
  113. BOOST_CHECK(2 == T::m_delete_calls);
  114. return EXIT_SUCCESS;
  115. }
  116. int test_main( int /* argc */, char* /* argv */[] ){
  117. if(EXIT_SUCCESS != test<ANew>())
  118. return EXIT_FAILURE;
  119. if(EXIT_SUCCESS != test<ANew1>())
  120. return EXIT_FAILURE;
  121. // Note the following test fails. To see why this is, look into the file
  122. // iserializer line # 247. Feel free to send a patch to detect the absense
  123. // of a class specific delete.
  124. /*
  125. if(EXIT_SUCCESS != test<ANew2>())
  126. return EXIT_FAILURE;
  127. */
  128. return EXIT_SUCCESS;
  129. }
  130. // EOF