]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/utility/test/value_init_test.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / utility / test / value_init_test.cpp
CommitLineData
7c673cae
FG
1// Copyright 2002-2008, Fernando Luis Cacciola Carballal.
2//
3// Distributed under the Boost Software License, Version 1.0. (See
4// accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6//
7// Test program for "boost/utility/value_init.hpp"
8//
9// 21 Ago 2002 (Created) Fernando Cacciola
10// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
11// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker
12// 21 Ago 2008 (Added swap test) Niels Dekker
13
14#include <cstring> // For memcmp.
15#include <iostream>
16#include <string>
17
18#include "boost/utility/value_init.hpp"
7c673cae
FG
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
11fdf7f2 24#include <boost/core/lightweight_test.hpp>
7c673cae
FG
25
26//
27// Sample POD type
28//
29struct POD
30{
31 POD () : f(0), c(0), i(0){}
32
33 POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {}
34
35 friend std::ostream& operator << ( std::ostream& os, POD const& pod )
36 { return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
37
38 friend bool operator == ( POD const& lhs, POD const& rhs )
39 { return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
40
41 float f;
42 char c;
43 int i;
44} ;
45
46//
47// Sample non POD type
48//
49struct NonPODBase
50{
51 virtual ~NonPODBase() {}
52} ;
53struct NonPOD : NonPODBase
54{
55 NonPOD () : id() {}
56 explicit NonPOD ( std::string const& id_) : id(id_) {}
57
58 friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
59 { return os << '(' << npod.id << ')' ; }
60
61 friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs )
62 { return lhs.id == rhs.id ; }
63
64 std::string id ;
65} ;
66
67//
68// Sample aggregate POD struct type
69// Some compilers do not correctly value-initialize such a struct, for example:
70// Borland C++ Report #51854, "Value-initialization: POD struct should be zero-initialized "
71// http://qc.codegear.com/wc/qcmain.aspx?d=51854
72//
73struct AggregatePODStruct
74{
75 float f;
76 char c;
77 int i;
78};
79
80bool operator == ( AggregatePODStruct const& lhs, AggregatePODStruct const& rhs )
81{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
82
83//
84// An aggregate struct that contains an std::string and an int.
85// Pavel Kuznetsov (MetaCommunications Engineering) used a struct like
86// this to reproduce the Microsoft Visual C++ compiler bug, reported as
87// Feedback ID 100744, "Value-initialization in new-expression"
88// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
89//
90struct StringAndInt
91{
92 std::string s;
93 int i;
94};
95
96bool operator == ( StringAndInt const& lhs, StringAndInt const& rhs )
97{ return lhs.s == rhs.s && lhs.i == rhs.i ; }
98
99
100//
101// A struct that has an explicit (user defined) destructor.
102// Some compilers do not correctly value-initialize such a struct, for example:
103// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
104// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
105//
106struct StructWithDestructor
107{
108 int i;
109 ~StructWithDestructor() {}
110};
111
112bool operator == ( StructWithDestructor const& lhs, StructWithDestructor const& rhs )
113{ return lhs.i == rhs.i ; }
114
115
116//
117// A struct that has a virtual function.
118// Some compilers do not correctly value-initialize such a struct either, for example:
119// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
120// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
121//
122struct StructWithVirtualFunction
123{
124 int i;
125 virtual void VirtualFunction();
126};
127
128void StructWithVirtualFunction::VirtualFunction()
129{
130}
131
132bool operator == ( StructWithVirtualFunction const& lhs, StructWithVirtualFunction const& rhs )
133{ return lhs.i == rhs.i ; }
134
135
136//
137// A struct that is derived from an aggregate POD struct.
138// Some compilers do not correctly value-initialize such a struct, for example:
139// GCC Bugzilla Bug 30111, "Value-initialization of POD base class doesn't initialize members",
140// reported by Jonathan Wakely, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
141//
142struct DerivedFromAggregatePODStruct : AggregatePODStruct
143{
144 DerivedFromAggregatePODStruct() : AggregatePODStruct() {}
145};
146
147//
148// A struct that wraps an aggregate POD struct as data member.
149//
150struct AggregatePODStructWrapper
151{
152 AggregatePODStructWrapper() : dataMember() {}
153 AggregatePODStruct dataMember;
154};
155
156bool operator == ( AggregatePODStructWrapper const& lhs, AggregatePODStructWrapper const& rhs )
157{ return lhs.dataMember == rhs.dataMember ; }
158
159typedef unsigned char ArrayOfBytes[256];
160
161
162//
163// A struct that allows testing whether the appropriate copy functions are called.
164//
165struct CopyFunctionCallTester
166{
167 bool is_copy_constructed;
168 bool is_assignment_called;
169
170 CopyFunctionCallTester()
171 : is_copy_constructed(false), is_assignment_called(false) {}
172
173 CopyFunctionCallTester(const CopyFunctionCallTester & )
174 : is_copy_constructed(true), is_assignment_called(false) {}
175
176 CopyFunctionCallTester & operator=(const CopyFunctionCallTester & )
177 {
178 is_assignment_called = true ;
179 return *this ;
180 }
181};
182
183
184//
185// A struct that allows testing whether its customized swap function is called.
186//
187struct SwapFunctionCallTester
188{
189 bool is_custom_swap_called;
190 int data;
191
192 SwapFunctionCallTester()
193 : is_custom_swap_called(false), data(0) {}
194
195 SwapFunctionCallTester(const SwapFunctionCallTester & arg)
196 : is_custom_swap_called(false), data(arg.data) {}
197
198 void swap(SwapFunctionCallTester & arg)
199 {
200 std::swap(data, arg.data);
201 is_custom_swap_called = true;
202 arg.is_custom_swap_called = true;
203 }
204};
205
206void swap(SwapFunctionCallTester & lhs, SwapFunctionCallTester & rhs)
207{
208 lhs.swap(rhs);
209}
210
211
212
213template<class T>
214void check_initialized_value ( T const& y )
215{
216 T initializedValue = boost::initialized_value ;
217 BOOST_TEST ( y == initializedValue ) ;
218}
219
220#ifdef __BORLANDC__
221#if __BORLANDC__ == 0x582
222void check_initialized_value( NonPOD const& )
223{
224 // The initialized_value check is skipped for Borland 5.82
225 // and this type (NonPOD), because the following statement
226 // won't compile on this particular compiler version:
227 // NonPOD initializedValue = boost::initialized_value() ;
228 //
229 // This is caused by a compiler bug, that is fixed with a newer version
230 // of the Borland compiler. The Release Notes for Delphi(R) 2007 for
231 // Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
232 // say about similar statements:
233 // both of these statements now compile but under 5.82 got the error:
234 // Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
235}
236#endif
237#endif
238
239//
240// This test function tests boost::value_initialized<T> for a specific type T.
241// The first argument (y) is assumed have the value of a value-initialized object.
242// Returns true on success.
243//
244template<class T>
245bool test ( T const& y, T const& z )
246{
247 const int errors_before_test = boost::detail::test_errors();
248
249 check_initialized_value(y);
250
251 boost::value_initialized<T> x ;
252 BOOST_TEST ( y == x ) ;
253 BOOST_TEST ( y == boost::get(x) ) ;
254
255 static_cast<T&>(x) = z ;
256 boost::get(x) = z ;
257 BOOST_TEST ( x == z ) ;
258
259 boost::value_initialized<T> const x_c ;
260 BOOST_TEST ( y == x_c ) ;
261 BOOST_TEST ( y == boost::get(x_c) ) ;
262 T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
263 x_c_ref = z ;
264 BOOST_TEST ( x_c == z ) ;
265
266 boost::value_initialized<T> const copy1 = x;
267 BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
268
269 boost::value_initialized<T> copy2;
270 copy2 = x;
271 BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
11fdf7f2
TL
272
273 {
274 boost::value_initialized<T> * ptr = new boost::value_initialized<T>;
275 BOOST_TEST ( y == *ptr ) ;
276 delete ptr;
277 }
7c673cae
FG
278
279#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
280 boost::value_initialized<T const> cx ;
281 BOOST_TEST ( y == cx ) ;
282 BOOST_TEST ( y == boost::get(cx) ) ;
283
284 boost::value_initialized<T const> const cx_c ;
285 BOOST_TEST ( y == cx_c ) ;
286 BOOST_TEST ( y == boost::get(cx_c) ) ;
287#endif
288
289 return boost::detail::test_errors() == errors_before_test ;
290}
291
11fdf7f2 292int main()
7c673cae
FG
293{
294 BOOST_TEST ( test( 0,1234 ) ) ;
295 BOOST_TEST ( test( 0.0,12.34 ) ) ;
296 BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
297 BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
298
299 NonPOD NonPOD_object( std::string("NonPOD_object") );
300 BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
301
302 AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
303 AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
304 BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
305
306 StringAndInt stringAndInt0;
307 StringAndInt stringAndInt1;
308 stringAndInt0.i = 0;
309 stringAndInt1.i = 1;
310 stringAndInt1.s = std::string("1");
311 BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
312
313 StructWithDestructor structWithDestructor0;
314 StructWithDestructor structWithDestructor1;
315 structWithDestructor0.i = 0;
316 structWithDestructor1.i = 1;
317 BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
318
319 StructWithVirtualFunction structWithVirtualFunction0;
320 StructWithVirtualFunction structWithVirtualFunction1;
321 structWithVirtualFunction0.i = 0;
322 structWithVirtualFunction1.i = 1;
323 BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
324
325 DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
326 DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
327 static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
328 static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
329 BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
330
331 AggregatePODStructWrapper aggregatePODStructWrapper0;
332 AggregatePODStructWrapper aggregatePODStructWrapper1;
333 aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
334 aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
335 BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
336
337 ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
338 boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
339 BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
340
341 boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
342 valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
343 BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
344
345 boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
346 BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
347 BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
348
349 boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
350 BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
351 BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
352
353 boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
354 copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
355 BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
356 BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
357
358 boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
359 boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
360 get(swapFunctionCallTester1).data = 1;
361 get(swapFunctionCallTester2).data = 2;
362 boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
363 BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
364 BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
365 BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
366 BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
367
368 return boost::report_errors();
369}
370
371