diff --git a/test/all/Jamfile.v2 b/test/all/Jamfile.v2 index 4b510a83..e33f87a0 100644 --- a/test/all/Jamfile.v2 +++ b/test/all/Jamfile.v2 @@ -1,7 +1,7 @@ # # Regression test Jamfile for boost configuration setup. # *** DO NOT EDIT THIS FILE BY HAND *** -# This file was automatically generated on Sun Oct 11 13:04:18 2009 +# This file was automatically generated on Fri Apr 09 12:24:54 2010 # by libs/config/tools/generate.cpp # Copyright John Maddock. # Use, modification and distribution are subject to the @@ -265,6 +265,9 @@ test-suite "BOOST_NO_CHAR16_T" : test-suite "BOOST_NO_CHAR32_T" : [ run ../no_char32_t_pass.cpp ] [ compile-fail ../no_char32_t_fail.cpp ] ; +test-suite "BOOST_NO_COMPLETE_VALUE_INITIALIZATION" : +[ run ../no_com_value_init_pass.cpp ] +[ compile-fail ../no_com_value_init_fail.cpp ] ; test-suite "BOOST_NO_CONCEPTS" : [ run ../no_concepts_pass.cpp ] [ compile-fail ../no_concepts_fail.cpp ] ; diff --git a/test/boost_no_com_value_init.ipp b/test/boost_no_com_value_init.ipp new file mode 100644 index 00000000..78df4edd --- /dev/null +++ b/test/boost_no_com_value_init.ipp @@ -0,0 +1,182 @@ +// (C) Copyright Niels Dekker 2010. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for most recent version. + +// MACRO: BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// TITLE: No complete value-initialization +// DESCRIPTION: The C++ compiler does not to have implemented value-initialization completely. +// See also boost/libs/utility/value_init.htm#compiler_issues + +#include +#include + +namespace boost_no_complete_value_initialization +{ + enum enum_type { negative_number = -1, magic_number = 42 }; + + // A POD struct. + struct pod_struct + { + enum_type e; + char c; + unsigned char uc; + short s; + int i; + unsigned u; + long l; + float f; + double d; + void* p; + }; + + bool is_zero_initialized(const pod_struct& arg) + { + return + arg.e == 0 && + arg.c == 0 && + arg.uc == 0 && + arg.s == 0 && + arg.i == 0 && + arg.u == 0 && + arg.l == 0 && + arg.f == 0 && + arg.d == 0 && + arg.p == 0; + } + + // A class that holds a "magic" enum value. + class enum_holder + { + enum_type m_enum; + public: + + enum_holder() + : + m_enum(magic_number) + { + } + + bool is_default() const + { + return m_enum == magic_number; + } + }; + + + // A class that is not a POD type. + class non_pod_class + { + private: + enum_holder m_enum_holder; + + public: + int i; + + virtual bool is_value_initialized() const + { + return m_enum_holder.is_default() && i == 0; + } + + virtual ~non_pod_class() {} + }; + + // The first argument (is_value_initializated) tells whether value initialization + // has succeeded. + // The second argument tells what expression was evaluated. + bool is_true(bool is_value_initializated, const char *const expression) + { + if ( ! is_value_initializated ) + { + std::cout + << "Information: " << expression << " evaluated to false.\n" + << std::endl; + } + return is_value_initializated; + } + +#define IS_TRUE(value) is_true(value, #value) +#define IS_ZERO(value) is_true(value == 0, #value " == 0") + + // The default constructor of this class initializes each of its + // data members by means of an empty set of parentheses, and checks + // whether each of them is value-initialized. + class value_initializer + { + private: + enum_holder m_enum_holder; + enum_type m_enum; + char m_char; + unsigned char m_unsigned_char; + short m_short; + int m_int; + unsigned m_unsigned; + long m_long; + float m_float; + double m_double; + void* m_ptr; + pod_struct m_pod; + pod_struct m_pod_array[2]; + non_pod_class m_non_pod; + non_pod_class m_non_pod_array[2]; + + public: + value_initializer() + : + m_enum_holder(), + m_enum(), + m_char(), + m_unsigned_char(), + m_short(), + m_int(), + m_unsigned(), + m_long(), + m_float(), + m_double(), + m_ptr(), + m_pod(), + m_pod_array(), + m_non_pod(), + m_non_pod_array() + { + } + + // Returns the number of failures. + unsigned check() const + { + return + (IS_TRUE( m_enum_holder.is_default() ) ? 0 : 1) + + (IS_ZERO(m_enum) ? 0 : 1) + + (IS_ZERO(m_char) ? 0 : 1) + + (IS_ZERO(m_unsigned_char) ? 0 : 1) + + (IS_ZERO(m_short) ? 0 : 1) + + (IS_ZERO(m_int) ? 0 : 1) + + (IS_ZERO(m_unsigned) ? 0 : 1) + + (IS_ZERO(m_long) ? 0 : 1) + + (IS_ZERO(m_float) ? 0 : 1) + + (IS_ZERO(m_double) ? 0 : 1) + + (IS_ZERO(m_ptr) ? 0 : 1) + + (IS_TRUE( is_zero_initialized(m_pod) ) ? 0 : 1) + + (IS_TRUE( m_non_pod.is_value_initialized() ) ? 0 : 1) + + (IS_TRUE( is_zero_initialized(m_pod_array[0]) + && is_zero_initialized(m_pod_array[1]) ) ? 0 : 1) + + (IS_TRUE( m_non_pod_array[0].is_value_initialized() + && m_non_pod_array[1].is_value_initialized() ) ? 0 : 1); + + } + }; + + int test() + { + // Check both value-initialization on the stack and on the heap: + const unsigned num_failures_on_stack = value_initializer().check(); + const value_initializer* const ptr = new value_initializer(); + const unsigned num_failures_on_heap = ptr->check(); + delete ptr; + return static_cast(num_failures_on_stack + num_failures_on_heap); + } + +} // End of namespace. + diff --git a/test/config_info.cpp b/test/config_info.cpp index 3b781432..62f906b1 100644 --- a/test/config_info.cpp +++ b/test/config_info.cpp @@ -985,6 +985,7 @@ void print_boost_macros() PRINT_MACRO(BOOST_NO_AUTO_PTR); PRINT_MACRO(BOOST_NO_CHAR16_T); PRINT_MACRO(BOOST_NO_CHAR32_T); + PRINT_MACRO(BOOST_NO_COMPLETE_VALUE_INITIALIZATION); PRINT_MACRO(BOOST_NO_CONCEPTS); PRINT_MACRO(BOOST_NO_CONSTEXPR); PRINT_MACRO(BOOST_NO_CTYPE_FUNCTIONS); @@ -1080,6 +1081,7 @@ void print_boost_macros() + // END GENERATED BLOCK PRINT_MACRO(BOOST_INTEL); diff --git a/test/config_test.cpp b/test/config_test.cpp index 81aee7c4..30c295d5 100644 --- a/test/config_test.cpp +++ b/test/config_test.cpp @@ -1,4 +1,4 @@ -// This file was automatically generated on Sun Oct 11 13:04:18 2009 +// This file was automatically generated on Fri Apr 09 12:24:54 2010 // by libs/config/tools/generate.cpp // Copyright John Maddock 2002-4. // Use, modification and distribution are subject to the @@ -172,6 +172,11 @@ namespace boost_no_char16_t = empty_boost; #else namespace boost_no_char32_t = empty_boost; #endif +#ifndef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#include "boost_no_com_value_init.ipp" +#else +namespace boost_no_complete_value_initialization = empty_boost; +#endif #ifndef BOOST_NO_CONCEPTS #include "boost_no_concepts.ipp" #else @@ -1251,6 +1256,11 @@ int main( int, char *[] ) std::cerr << "Failed test for BOOST_NO_CHAR32_T at: " << __FILE__ << ":" << __LINE__ << std::endl; ++error_count; } + if(0 != boost_no_complete_value_initialization::test()) + { + std::cerr << "Failed test for BOOST_NO_COMPLETE_VALUE_INITIALIZATION at: " << __FILE__ << ":" << __LINE__ << std::endl; + ++error_count; + } if(0 != boost_no_concepts::test()) { std::cerr << "Failed test for BOOST_NO_CONCEPTS at: " << __FILE__ << ":" << __LINE__ << std::endl; diff --git a/test/no_com_value_init_fail.cpp b/test/no_com_value_init_fail.cpp new file mode 100644 index 00000000..ec89a858 --- /dev/null +++ b/test/no_com_value_init_fail.cpp @@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Apr 09 12:24:53 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// This file should not compile, if it does then +// BOOST_NO_COMPLETE_VALUE_INITIALIZATION should not be defined. +// See file boost_no_com_value_init.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include +#include "test.hpp" + +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#include "boost_no_com_value_init.ipp" +#else +#error "this file should not compile" +#endif + +int main( int, char *[] ) +{ + return boost_no_complete_value_initialization::test(); +} + diff --git a/test/no_com_value_init_pass.cpp b/test/no_com_value_init_pass.cpp new file mode 100644 index 00000000..cfe00a22 --- /dev/null +++ b/test/no_com_value_init_pass.cpp @@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Apr 09 12:24:53 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// This file should compile, if it does not then +// BOOST_NO_COMPLETE_VALUE_INITIALIZATION should be defined. +// See file boost_no_com_value_init.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include +#include "test.hpp" + +#ifndef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#include "boost_no_com_value_init.ipp" +#else +namespace boost_no_complete_value_initialization = empty_boost; +#endif + +int main( int, char *[] ) +{ + return boost_no_complete_value_initialization::test(); +} +