Squashed 'third_party/boostorg/utility/' content from commit ebe4429

Change-Id: I8e6ee78273db31df18f99d29034f855ccc064551
git-subtree-dir: third_party/boostorg/utility
git-subtree-split: ebe44296ca698e333a09e8268ea8ccedb3886c4d
diff --git a/test/value_init_workaround_test.cpp b/test/value_init_workaround_test.cpp
new file mode 100644
index 0000000..9ffdffc
--- /dev/null
+++ b/test/value_init_workaround_test.cpp
@@ -0,0 +1,163 @@
+// 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.
+//
+// 17 June 2010 (Created) Niels Dekker
+
+// 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;
+  }
+
+  // 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;
+  }
+
+  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;
+  }
+
+  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>()) +
+    FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
+    FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) +
+    FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>());
+
+#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
+}