| 
									
										
										
										
											2010-06-16 08:45:43 +00:00
										 |  |  | // Copyright 2010, Niels Dekker.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Distributed under the Boost Software License, Version 1.0. (See
 | 
					
						
							|  |  |  | // accompanying file LICENSE_1_0.txt or copy at
 | 
					
						
							|  |  |  | // http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Test program for the boost::value_initialized<T> workaround.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2010-06-17 16:53:55 +00:00
										 |  |  | // 17 June 2010 (Created) Niels Dekker
 | 
					
						
							| 
									
										
										
										
											2010-06-16 08:45:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Switch the workaround off, before inluding "value_init.hpp".
 | 
					
						
							|  |  |  | #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
 | 
					
						
							|  |  |  | #include <boost/utility/value_init.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <iostream>  // For cout.
 | 
					
						
							|  |  |  | #include <cstdlib>  // For EXIT_SUCCESS and EXIT_FAILURE.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct empty_struct | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // A POD aggregate struct derived from an empty struct.
 | 
					
						
							|  |  |  |   // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
 | 
					
						
							|  |  |  |   // "VC++ does not value-initialize members of derived classes without 
 | 
					
						
							|  |  |  |   // user-declared constructor", reported in 2009 by Sylvester Hesp:
 | 
					
						
							|  |  |  |   // https://connect.microsoft.com/VisualStudio/feedback/details/484295
 | 
					
						
							|  |  |  |   struct derived_struct: empty_struct | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     int data; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool is_value_initialized(const derived_struct& arg) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return arg.data == 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class virtual_destructor_holder | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     virtual ~virtual_destructor_holder() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool is_value_initialized(const virtual_destructor_holder& arg) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return arg.i == 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-17 16:53:55 +00:00
										 |  |  |   // Equivalent to the Stats class from GCC Bug 33916,
 | 
					
						
							|  |  |  |   // "Default constructor fails to initialize array members", reported in 2007 by
 | 
					
						
							|  |  |  |   // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
 | 
					
						
							|  |  |  |   // and fixed for GCC 4.2.4.
 | 
					
						
							|  |  |  |   class private_int_array_pair | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     friend bool is_value_initialized(const private_int_array_pair& arg); | 
					
						
							|  |  |  |   private: | 
					
						
							|  |  |  |     int first[12]; | 
					
						
							|  |  |  |     int second[12]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool is_value_initialized(const private_int_array_pair& arg) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     for ( unsigned i = 0; i < 12; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if ( (arg.first[i] != 0) || (arg.second[i] != 0) ) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 12:47:05 +03:00
										 |  |  |   struct int_pair_struct | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     int first; | 
					
						
							|  |  |  |     int second; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   typedef int int_pair_struct::*ptr_to_member_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct ptr_to_member_struct | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ptr_to_member_type data; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool is_value_initialized(const ptr_to_member_struct& arg) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return arg.data == 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-16 08:45:43 +00:00
										 |  |  |   template <typename T> | 
					
						
							|  |  |  |   bool is_value_initialized(const T(& arg)[2]) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return | 
					
						
							|  |  |  |       is_value_initialized(arg[0]) && | 
					
						
							|  |  |  |       is_value_initialized(arg[1]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							|  |  |  |   bool is_value_initialized(const boost::value_initialized<T>& arg) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return is_value_initialized(arg.data()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Returns zero when the specified object is value-initializated, and one otherwise.
 | 
					
						
							|  |  |  |   // Prints a message to standard output if the value-initialization has failed.
 | 
					
						
							|  |  |  |   template <class T> | 
					
						
							|  |  |  |   unsigned failed_to_value_initialized(const T& object, const char *const object_name) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if ( is_value_initialized(object) ) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return 0u; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl; | 
					
						
							|  |  |  |       return 1u; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A macro that passed both the name and the value of the specified object to
 | 
					
						
							|  |  |  | // the function above here.
 | 
					
						
							|  |  |  | #define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Equivalent to the dirty_stack() function from GCC Bug 33916,
 | 
					
						
							|  |  |  |   // "Default constructor fails to initialize array members", reported in 2007 by
 | 
					
						
							|  |  |  |   // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
 | 
					
						
							|  |  |  |   void dirty_stack() | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     unsigned char array_on_stack[4096]; | 
					
						
							|  |  |  |     for (unsigned i = 0; i < sizeof(array_on_stack); ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       array_on_stack[i] = 0x11; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   dirty_stack(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // TODO More types may be added later.
 | 
					
						
							|  |  |  |   const unsigned num_failures = | 
					
						
							|  |  |  |     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) + | 
					
						
							| 
									
										
										
										
											2010-06-17 16:53:55 +00:00
										 |  |  |     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) + | 
					
						
							| 
									
										
										
										
											2017-09-24 12:47:05 +03:00
										 |  |  |     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) + | 
					
						
							|  |  |  |     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>()); | 
					
						
							| 
									
										
										
										
											2010-06-16 08:45:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
 | 
					
						
							|  |  |  |   // One or more failures are expected.
 | 
					
						
							|  |  |  |   return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   // No failures are expected.
 | 
					
						
							|  |  |  |   return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } |