diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc
index 6c4b3000..f3f49a68 100644
--- a/googlemock/test/gmock-generated-matchers_test.cc
+++ b/googlemock/test/gmock-generated-matchers_test.cc
@@ -41,6 +41,8 @@
 
 #include "gmock/gmock-generated-matchers.h"
 
+#include <array>
+#include <iterator>
 #include <list>
 #include <map>
 #include <memory>
@@ -51,8 +53,8 @@
 #include <vector>
 
 #include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
 
 namespace {
 
@@ -195,7 +197,7 @@ TEST(ElementsAreTest, ExplainsNonTrivialMatch) {
       ElementsAre(GreaterThan(1), 0, GreaterThan(2));
 
   const int a[] = { 10, 0, 100 };
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> test_vector(std::begin(a), std::end(a));
   EXPECT_EQ("whose element #0 matches, which is 9 more than 1,\n"
             "and whose element #2 matches, which is 98 more than 2",
             Explain(m, test_vector));
@@ -280,7 +282,7 @@ TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) {
 
 TEST(ElementsAreTest, MatchesTenElementVector) {
   const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> test_vector(std::begin(a), std::end(a));
 
   EXPECT_THAT(test_vector,
               // The element list can contain values and/or matchers
@@ -317,13 +319,10 @@ TEST(ElementsAreTest, DoesNotMatchWrongOrder) {
 }
 
 TEST(ElementsAreTest, WorksForNestedContainer) {
-  const char* strings[] = {
-    "Hi",
-    "world"
-  };
+  constexpr std::array<const char*, 2> strings = {{"Hi", "world"}};
 
   vector<list<char> > nested;
-  for (size_t i = 0; i < GTEST_ARRAY_SIZE_(strings); i++) {
+  for (size_t i = 0; i < strings.size(); i++) {
     nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i])));
   }
 
@@ -335,7 +334,7 @@ TEST(ElementsAreTest, WorksForNestedContainer) {
 
 TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
   int a[] = { 0, 1, 2 };
-  vector<int> v(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> v(std::begin(a), std::end(a));
 
   EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2])));
   EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2]))));
@@ -343,7 +342,7 @@ TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
 
 TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
   int a[] = { 0, 1, 2 };
-  vector<int> v(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> v(std::begin(a), std::end(a));
 
   EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _)));
   EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
@@ -440,7 +439,7 @@ TEST(ElementsAreTest, MakesCopyOfArguments) {
 TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
   const int a[] = { 1, 2, 3 };
 
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> test_vector(std::begin(a), std::end(a));
   EXPECT_THAT(test_vector, ElementsAreArray(a));
 
   test_vector[2] = 0;
@@ -448,20 +447,20 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
 }
 
 TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) {
-  const char* a[] = { "one", "two", "three" };
+  std::array<const char*, 3> a = {{"one", "two", "three"}};
 
-  vector<std::string> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
-  EXPECT_THAT(test_vector, ElementsAreArray(a, GTEST_ARRAY_SIZE_(a)));
+  vector<std::string> test_vector(std::begin(a), std::end(a));
+  EXPECT_THAT(test_vector, ElementsAreArray(a.data(), a.size()));
 
-  const char** p = a;
+  const char** p = a.data();
   test_vector[0] = "1";
-  EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GTEST_ARRAY_SIZE_(a))));
+  EXPECT_THAT(test_vector, Not(ElementsAreArray(p, a.size())));
 }
 
 TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) {
   const char* a[] = { "one", "two", "three" };
 
-  vector<std::string> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<std::string> test_vector(std::begin(a), std::end(a));
   EXPECT_THAT(test_vector, ElementsAreArray(a));
 
   test_vector[0] = "1";
@@ -484,8 +483,8 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
 
 TEST(ElementsAreArrayTest, CanBeCreatedWithVector) {
   const int a[] = { 1, 2, 3 };
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
-  const vector<int> expected(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> test_vector(std::begin(a), std::end(a));
+  const vector<int> expected(std::begin(a), std::end(a));
   EXPECT_THAT(test_vector, ElementsAreArray(expected));
   test_vector.push_back(4);
   EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
@@ -530,9 +529,9 @@ TEST(ElementsAreArrayTest,
 TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) {
   const int a[] = { 1, 2, 3 };
   const Matcher<int> kMatchers[] = { Eq(1), Eq(2), Eq(3) };
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
-  const vector<Matcher<int> > expected(
-      kMatchers, kMatchers + GTEST_ARRAY_SIZE_(kMatchers));
+  vector<int> test_vector(std::begin(a), std::end(a));
+  const vector<Matcher<int>> expected(std::begin(kMatchers),
+                                      std::end(kMatchers));
   EXPECT_THAT(test_vector, ElementsAreArray(expected));
   test_vector.push_back(4);
   EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
@@ -540,11 +539,11 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) {
 
 TEST(ElementsAreArrayTest, CanBeCreatedWithIteratorRange) {
   const int a[] = { 1, 2, 3 };
-  const vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
-  const vector<int> expected(a, a + GTEST_ARRAY_SIZE_(a));
+  const vector<int> test_vector(std::begin(a), std::end(a));
+  const vector<int> expected(std::begin(a), std::end(a));
   EXPECT_THAT(test_vector, ElementsAreArray(expected.begin(), expected.end()));
   // Pointers are iterators, too.
-  EXPECT_THAT(test_vector, ElementsAreArray(a, a + GTEST_ARRAY_SIZE_(a)));
+  EXPECT_THAT(test_vector, ElementsAreArray(std::begin(a), std::end(a)));
   // The empty range of NULL pointers should also be okay.
   int* const null_int = nullptr;
   EXPECT_THAT(test_vector, Not(ElementsAreArray(null_int, null_int)));
@@ -564,8 +563,8 @@ TEST(ElementsAreArrayTest, WorksWithNativeArray) {
 
 TEST(ElementsAreArrayTest, SourceLifeSpan) {
   const int a[] = { 1, 2, 3 };
-  vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a));
-  vector<int> expect(a, a + GTEST_ARRAY_SIZE_(a));
+  vector<int> test_vector(std::begin(a), std::end(a));
+  vector<int> expect(std::begin(a), std::end(a));
   ElementsAreArrayMatcher<int> matcher_maker =
       ElementsAreArray(expect.begin(), expect.end());
   EXPECT_THAT(test_vector, matcher_maker);
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index b9eb894d..bc49cb62 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -41,10 +41,11 @@
 #endif
 
 #include "gmock/gmock-matchers.h"
-#include "gmock/gmock-more-matchers.h"
 
 #include <string.h>
 #include <time.h>
+
+#include <array>
 #include <deque>
 #include <forward_list>
 #include <functional>
@@ -60,9 +61,11 @@
 #include <type_traits>
 #include <utility>
 #include <vector>
+
+#include "gmock/gmock-more-matchers.h"
 #include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
 
 namespace testing {
 namespace gmock_matchers_test {
@@ -5201,14 +5204,14 @@ TEST(WhenSortedTest, WorksForStreamlike) {
   // Streamlike 'container' provides only minimal iterator support.
   // Its iterators are tagged with input_iterator_tag.
   const int a[5] = {2, 1, 4, 5, 3};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
   EXPECT_THAT(s, WhenSorted(ElementsAre(1, 2, 3, 4, 5)));
   EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3))));
 }
 
 TEST(WhenSortedTest, WorksForVectorConstRefMatcherOnStreamlike) {
   const int a[] = {2, 1, 4, 5, 3};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
   Matcher<const std::vector<int>&> vector_match = ElementsAre(1, 2, 3, 4, 5);
   EXPECT_THAT(s, WhenSorted(vector_match));
   EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3))));
@@ -5253,7 +5256,7 @@ TEST(IsSupersetOfTest, WorksForEmpty) {
 
 TEST(IsSupersetOfTest, WorksForStreamlike) {
   const int a[5] = {1, 2, 3, 4, 5};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
 
   vector<int> expected;
   expected.push_back(1);
@@ -5381,7 +5384,7 @@ TEST(IsSubsetOfTest, WorksForEmpty) {
 
 TEST(IsSubsetOfTest, WorksForStreamlike) {
   const int a[5] = {1, 2};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
 
   vector<int> expected;
   expected.push_back(1);
@@ -5475,14 +5478,14 @@ TEST(IsSubsetOfTest, WorksWithMoveOnly) {
 
 TEST(ElemensAreStreamTest, WorksForStreamlike) {
   const int a[5] = {1, 2, 3, 4, 5};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
   EXPECT_THAT(s, ElementsAre(1, 2, 3, 4, 5));
   EXPECT_THAT(s, Not(ElementsAre(2, 1, 4, 5, 3)));
 }
 
 TEST(ElemensAreArrayStreamTest, WorksForStreamlike) {
   const int a[5] = {1, 2, 3, 4, 5};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
 
   vector<int> expected;
   expected.push_back(1);
@@ -5529,7 +5532,7 @@ TEST(ElementsAreTest, TakesStlContainer) {
 
 TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) {
   const int a[] = {0, 1, 2, 3, 4};
-  std::vector<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  std::vector<int> s(std::begin(a), std::end(a));
   do {
     StringMatchResultListener listener;
     EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(a),
@@ -5540,8 +5543,8 @@ TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) {
 TEST(UnorderedElementsAreArrayTest, VectorBool) {
   const bool a[] = {0, 1, 0, 1, 1};
   const bool b[] = {1, 0, 1, 1, 0};
-  std::vector<bool> expected(a, a + GTEST_ARRAY_SIZE_(a));
-  std::vector<bool> actual(b, b + GTEST_ARRAY_SIZE_(b));
+  std::vector<bool> expected(std::begin(a), std::end(a));
+  std::vector<bool> actual(std::begin(b), std::end(b));
   StringMatchResultListener listener;
   EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(expected),
                                  actual, &listener)) << listener.str();
@@ -5552,7 +5555,7 @@ TEST(UnorderedElementsAreArrayTest, WorksForStreamlike) {
   // Its iterators are tagged with input_iterator_tag, and it has no
   // size() or empty() methods.
   const int a[5] = {2, 1, 4, 5, 3};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
 
   ::std::vector<int> expected;
   expected.push_back(1);
@@ -5635,7 +5638,7 @@ TEST_F(UnorderedElementsAreTest, WorksWithUncopyable) {
 
 TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) {
   const int a[] = {1, 2, 3};
-  std::vector<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  std::vector<int> s(std::begin(a), std::end(a));
   do {
     StringMatchResultListener listener;
     EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3),
@@ -5645,7 +5648,7 @@ TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) {
 
 TEST_F(UnorderedElementsAreTest, FailsWhenAnElementMatchesNoMatcher) {
   const int a[] = {1, 2, 3};
-  std::vector<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  std::vector<int> s(std::begin(a), std::end(a));
   std::vector<Matcher<int> > mv;
   mv.push_back(1);
   mv.push_back(2);
@@ -5661,7 +5664,7 @@ TEST_F(UnorderedElementsAreTest, WorksForStreamlike) {
   // Its iterators are tagged with input_iterator_tag, and it has no
   // size() or empty() methods.
   const int a[5] = {2, 1, 4, 5, 3};
-  Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a));
+  Streamlike<int> s(std::begin(a), std::end(a));
 
   EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
   EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5)));
@@ -5977,8 +5980,9 @@ TEST_F(BipartiteNonSquareTest, SimpleBacktracking) {
   //  :.......:
   //    0 1 2
   MatchMatrix g(4, 3);
-  static const size_t kEdges[][2] = {{0, 2}, {1, 1}, {2, 1}, {3, 0}};
-  for (size_t i = 0; i < GTEST_ARRAY_SIZE_(kEdges); ++i) {
+  constexpr std::array<std::array<size_t, 2>, 4> kEdges = {
+      {{{0, 2}}, {{1, 1}}, {{2, 1}}, {{3, 0}}}};
+  for (size_t i = 0; i < kEdges.size(); ++i) {
     g.SetEdge(kEdges[i][0], kEdges[i][1], true);
   }
   EXPECT_THAT(FindBacktrackingMaxBPM(g),
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index dc67902b..3ad7119c 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -844,9 +844,6 @@ class Secret;
 // expression is false, compiler will issue an error containing this identifier.
 #define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
 
-// Evaluates to the number of elements in 'array'.
-#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
-
 // A helper for suppressing warnings on constant condition.  It just
 // returns 'condition'.
 GTEST_API_ bool IsTrue(bool condition);