Merge pull request #1218 from KindDragon/vs-build-fix

VS2015/2017 build fix and enable C++11 features (attempt number three)
diff --git a/.gitignore b/.gitignore
index 8f89b80..4cea432 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,16 @@
 bazel-out
 bazel-testlogs
 # python
-*.pyc
\ No newline at end of file
+*.pyc
+
+# Visual Studio files
+*.sdf
+*.opensdf
+*.VC.opendb
+*.suo
+*.user
+_ReSharper.Caches/
+Win32-Debug/
+Win32-Release/
+x64-Debug/
+x64-Release/
diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc
index 8234858..6cba726 100644
--- a/googlemock/test/gmock-generated-matchers_test.cc
+++ b/googlemock/test/gmock-generated-matchers_test.cc
@@ -120,7 +120,7 @@
 }
 
 TEST(ArgsTest, AcceptsTwoTemplateArgs) {
-  const tuple<short, int, long> t(4, 5, 6L);  // NOLINT
+  const tuple<short, int, long> t(static_cast<short>(4), 5, 6L);  // NOLINT
 
   EXPECT_THAT(t, (Args<0, 1>(Lt())));
   EXPECT_THAT(t, (Args<1, 2>(Lt())));
@@ -128,13 +128,13 @@
 }
 
 TEST(ArgsTest, AcceptsRepeatedTemplateArgs) {
-  const tuple<short, int, long> t(4, 5, 6L);  // NOLINT
+  const tuple<short, int, long> t(static_cast<short>(4), 5, 6L);  // NOLINT
   EXPECT_THAT(t, (Args<0, 0>(Eq())));
   EXPECT_THAT(t, Not(Args<1, 1>(Ne())));
 }
 
 TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
-  const tuple<short, int, long> t(4, 5, 6L);  // NOLINT
+  const tuple<short, int, long> t(static_cast<short>(4), 5, 6L);  // NOLINT
   EXPECT_THAT(t, (Args<2, 0>(Gt())));
   EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
 }
@@ -159,7 +159,7 @@
 }
 
 TEST(ArgsTest, CanBeNested) {
-  const tuple<short, int, long, int> t(4, 5, 6L, 6);  // NOLINT
+  const tuple<short, int, long, int> t(static_cast<short>(4), 5, 6L, 6);  // NOLINT
   EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq()))));
   EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt()))));
 }
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index fc86748..4beaec4 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -58,6 +58,11 @@
 # include <forward_list>  // NOLINT
 #endif
 
+// Disable MSVC2015 warning for std::pair: "decorated name length exceeded, name was truncated".
+#if defined(_MSC_VER) && (_MSC_VER == 1900)
+# pragma warning(disable:4503)
+#endif
+
 namespace testing {
 
 namespace internal {
@@ -3931,8 +3936,11 @@
 
 // Tests that ResultOf(f, ...) compiles and works as expected when f is a
 // function object.
-struct Functor : public ::std::unary_function<int, std::string> {
-  result_type operator()(argument_type input) const {
+struct Functor {
+  typedef std::string result_type;
+  typedef int argument_type;
+
+  std::string operator()(int input) const {
     return IntToStringFunction(input);
   }
 };
diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake
index 9915c11..c54bc94 100644
--- a/googletest/cmake/internal_utils.cmake
+++ b/googletest/cmake/internal_utils.cmake
@@ -87,10 +87,6 @@
       # http://stackoverflow.com/questions/3232669 explains the issue.
       set(cxx_base_flags "${cxx_base_flags} -wd4702")
     endif()
-    if (NOT (MSVC_VERSION GREATER 1900))  # 1900 is Visual Studio 2015
-      # BigObj required for tests.
-      set(cxx_base_flags "${cxx_base_flags} -bigobj")
-    endif()
 
     set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
     set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
@@ -187,6 +183,10 @@
 # is built from the given source files with the given compiler flags.
 function(cxx_executable_with_flags name cxx_flags libs)
   add_executable(${name} ${ARGN})
+  if (MSVC AND (NOT (MSVC_VERSION LESS 1700)))  # 1700 is Visual Studio 2012.
+    # BigObj required for tests.
+    set(cxx_flags "${cxx_flags} -bigobj")
+  endif()
   if (cxx_flags)
     set_target_properties(${name}
       PROPERTIES
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index 5529ba5..331483e 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -325,7 +325,7 @@
 // -std={c,gnu}++{0x,11} is passed.  The C++11 standard specifies a
 // value for __cplusplus, and recent versions of clang, gcc, and
 // probably other compilers set that too in C++11 mode.
-# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L
+# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L || _MSC_VER >= 1900
 // Compiling in at least C++11 mode.
 #  define GTEST_LANG_CXX11 1
 # else
@@ -357,12 +357,16 @@
 #if GTEST_STDLIB_CXX11
 # define GTEST_HAS_STD_BEGIN_AND_END_ 1
 # define GTEST_HAS_STD_FORWARD_LIST_ 1
-# define GTEST_HAS_STD_FUNCTION_ 1
+# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) // works only with VS2015U2 and better
+#   define GTEST_HAS_STD_FUNCTION_ 1
+# endif
 # define GTEST_HAS_STD_INITIALIZER_LIST_ 1
 # define GTEST_HAS_STD_MOVE_ 1
 # define GTEST_HAS_STD_SHARED_PTR_ 1
 # define GTEST_HAS_STD_TYPE_TRAITS_ 1
 # define GTEST_HAS_STD_UNIQUE_PTR_ 1
+# define GTEST_HAS_UNORDERED_MAP_ 1
+# define GTEST_HAS_UNORDERED_SET_ 1
 #endif
 
 // C++11 specifies that <tuple> provides std::tuple.
@@ -660,7 +664,8 @@
 // support TR1 tuple.  libc++ only provides std::tuple, in C++11 mode,
 // and it can be used with some compilers that define __GNUC__.
 # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \
-      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600
+      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) \
+      || (_MSC_VER >= 1600 && _MSC_VER < 1900)
 #  define GTEST_ENV_HAS_TR1_TUPLE_ 1
 # endif
 
diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc
index 487d3cb..2a6c017 100644
--- a/googletest/test/gtest-printers_test.cc
+++ b/googletest/test/gtest-printers_test.cc
@@ -51,10 +51,15 @@
 #include "gtest/gtest.h"
 
 // hash_map and hash_set are available under Visual C++, or on Linux.
-#if GTEST_HAS_HASH_MAP_
+#if GTEST_HAS_UNORDERED_MAP_
+# include <unordered_map>       // NOLINT
+#elif GTEST_HAS_HASH_MAP_
 # include <hash_map>            // NOLINT
 #endif  // GTEST_HAS_HASH_MAP_
-#if GTEST_HAS_HASH_SET_
+
+#if GTEST_HAS_UNORDERED_SET_
+# include <unordered_set>       // NOLINT
+#elif GTEST_HAS_HASH_SET_
 # include <hash_set>            // NOLINT
 #endif  // GTEST_HAS_HASH_SET_
 
@@ -239,21 +244,47 @@
 #endif
 using ::testing::internal::string;
 
-#if GTEST_HAS_HASH_MAP_
 // The hash_* classes are not part of the C++ standard.  STLport
 // defines them in namespace std.  MSVC defines them in ::stdext.  GCC
 // defines them in ::.
+#if GTEST_HAS_UNORDERED_MAP_
+
+#define GTEST_HAS_HASH_MAP_ 1
+template<class Key, class T>
+using hash_map = ::std::unordered_map<Key, T>;
+template<class Key, class T>
+using hash_multimap = ::std::unordered_multimap<Key, T>;
+
+#elif GTEST_HAS_HASH_MAP_
+
 #ifdef _STLP_HASH_MAP  // We got <hash_map> from STLport.
 using ::std::hash_map;
-using ::std::hash_set;
 using ::std::hash_multimap;
-using ::std::hash_multiset;
 #elif _MSC_VER
 using ::stdext::hash_map;
-using ::stdext::hash_set;
 using ::stdext::hash_multimap;
+#endif
+
+#endif
+
+#if GTEST_HAS_UNORDERED_SET_
+
+#define GTEST_HAS_HASH_SET_ 1
+template<class Key>
+using hash_set = ::std::unordered_set<Key>;
+template<class Key>
+using hash_multiset = ::std::unordered_multiset<Key>;
+
+#elif GTEST_HAS_HASH_SET_
+
+#ifdef _STLP_HASH_MAP  // We got <hash_map> from STLport.
+using ::std::hash_set;
+using ::std::hash_multiset;
+#elif _MSC_VER
+using ::stdext::hash_set;
 using ::stdext::hash_multiset;
 #endif
+
 #endif
 
 // Prints a value to a string using the universal value printer.  This
@@ -1061,8 +1092,8 @@
   ::std::tr1::tuple<bool, char, short, testing::internal::Int32,  // NOLINT
                     testing::internal::Int64, float, double, const char*, void*,
                     std::string>
-      t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, ImplicitCast_<void*>(NULL),
-          "10");
+      t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, 
+          ImplicitCast_<void*>(NULL), "10");
   EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
             " pointing to \"8\", NULL, \"10\")",
             Print(t10));
@@ -1121,8 +1152,8 @@
   ::std::tuple<bool, char, short, testing::internal::Int32,  // NOLINT
                testing::internal::Int64, float, double, const char*, void*,
                std::string>
-      t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, ImplicitCast_<void*>(NULL),
-          "10");
+      t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str,
+          ImplicitCast_<void*>(NULL), "10");
   EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
             " pointing to \"8\", NULL, \"10\")",
             Print(t10));
diff --git a/googletest/test/gtest_catch_exceptions_test_.cc b/googletest/test/gtest_catch_exceptions_test_.cc
index b42637e..c6d953c 100644
--- a/googletest/test/gtest_catch_exceptions_test_.cc
+++ b/googletest/test/gtest_catch_exceptions_test_.cc
@@ -138,7 +138,7 @@
 }
 
 // Exceptions in destructors are not supported in C++11.
-#if !defined(__GXX_EXPERIMENTAL_CXX0X__) &&  __cplusplus < 201103L && _MSC_VER < 1900
+#if !GTEST_LANG_CXX11
 class CxxExceptionInDestructorTest : public Test {
  public:
   static void TearDownTestCase() {