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