libstdc++: Move code after an early exit constexpr if to under an else branch
authorPatrick Palka <ppalka@redhat.com>
Sat, 15 Feb 2020 15:59:36 +0000 (10:59 -0500)
committerPatrick Palka <ppalka@redhat.com>
Sun, 16 Feb 2020 02:16:00 +0000 (21:16 -0500)
This avoids instantiating dead code when the true branch of the constexpr if is
taken.

libstdc++-v3/ChangeLog:

* include/bits/ranges_algo.h (__lexicographical_compare_fn::operator()):
Move code after an early exit constexpr if to under an else branch.
* include/bits/ranges_algobase.h (__equal_fn::operator()): Likewise.

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/ranges_algo.h
libstdc++-v3/include/bits/ranges_algobase.h

index b57ac9658e841ab22431e398c3d66adf79c8253f..25fa9ba6098ead05d998675b6699276862f1ad64 100644 (file)
@@ -1,3 +1,9 @@
+2020-02-16  Patrick Palka  <ppalka@redhat.com>
+
+       * include/bits/ranges_algo.h (__lexicographical_compare_fn::operator()):
+       Move code after an early exit constexpr if to under an else branch.
+       * include/bits/ranges_algobase.h (__equal_fn::operator()): Likewise.
+
 2020-02-15  Patrick Palka  <ppalka@redhat.com>
 
        * include/bits/ranges_algo.h: Adjust whitespace and formatting.
index 7f8f0fb964b280de25a3fbb84375472c4dc6f8c2..ff1b40f6ace1c5d5547a31ea1bb4c2fa38cbeecb 100644 (file)
@@ -3318,65 +3318,68 @@ namespace ranges
                         std::__niter_base(std::move(__last2)),
                         std::move(__comp),
                         std::move(__proj1), std::move(__proj2));
-
-       constexpr bool __sized_iters
-         = (sized_sentinel_for<_Sent1, _Iter1>
-            && sized_sentinel_for<_Sent2, _Iter2>);
-       if constexpr (__sized_iters)
+       else
          {
-           auto __d1 = ranges::distance(__first1, __last1);
-           auto __d2 = ranges::distance(__first2, __last2);
-
-           using _ValueType1 = iter_value_t<_Iter1>;
-           using _ValueType2 = iter_value_t<_Iter2>;
-           constexpr bool __use_memcmp
-             = ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>)
-                && is_same_v<_ValueType1, _ValueType2>
-                && is_pointer_v<_Iter1>
-                && is_pointer_v<_Iter2>
-                && (is_same_v<_Comp, ranges::less>
-                    || is_same_v<_Comp, ranges::greater>)
-                && is_same_v<_Proj1, identity>
-                && is_same_v<_Proj2, identity>);
-           if constexpr (__use_memcmp)
+           constexpr bool __sized_iters
+             = (sized_sentinel_for<_Sent1, _Iter1>
+                && sized_sentinel_for<_Sent2, _Iter2>);
+           if constexpr (__sized_iters)
              {
-               if (const auto __len = std::min(__d1, __d2))
+               auto __d1 = ranges::distance(__first1, __last1);
+               auto __d2 = ranges::distance(__first2, __last2);
+
+               using _ValueType1 = iter_value_t<_Iter1>;
+               using _ValueType2 = iter_value_t<_Iter2>;
+               constexpr bool __use_memcmp
+                 = ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>)
+                    && is_same_v<_ValueType1, _ValueType2>
+                    && is_pointer_v<_Iter1>
+                    && is_pointer_v<_Iter2>
+                    && (is_same_v<_Comp, ranges::less>
+                        || is_same_v<_Comp, ranges::greater>)
+                    && is_same_v<_Proj1, identity>
+                    && is_same_v<_Proj2, identity>);
+               if constexpr (__use_memcmp)
                  {
-                   const auto __c = std::__memcmp(__first1, __first2, __len);
-                   if constexpr (is_same_v<_Comp, ranges::less>)
-                     {
-                       if (__c < 0)
-                         return true;
-                       if (__c > 0)
-                         return false;
-                     }
-                   else if constexpr (is_same_v<_Comp, ranges::greater>)
+                   if (const auto __len = std::min(__d1, __d2))
                      {
-                       if (__c > 0)
-                         return true;
-                       if (__c < 0)
-                         return false;
+                       const auto __c
+                         = std::__memcmp(__first1, __first2, __len);
+                       if constexpr (is_same_v<_Comp, ranges::less>)
+                         {
+                           if (__c < 0)
+                             return true;
+                           if (__c > 0)
+                             return false;
+                         }
+                       else if constexpr (is_same_v<_Comp, ranges::greater>)
+                         {
+                           if (__c > 0)
+                             return true;
+                           if (__c < 0)
+                             return false;
+                         }
+                       else
+                         __builtin_unreachable();
                      }
-                   else
-                     __builtin_unreachable();
+                   return (__last1 - __first1 < __last2 - __first2);
                  }
-               return (__last1 - __first1 < __last2 - __first2);
              }
-         }
 
-       for (; __first1 != __last1 && __first2 != __last2;
-            ++__first1, (void) ++__first2)
-         {
-           if (std::__invoke(__comp,
-                             std::__invoke(__proj1, *__first1),
-                             std::__invoke(__proj2, *__first2)))
-             return true;
-           if (std::__invoke(__comp,
-                             std::__invoke(__proj2, *__first2),
-                             std::__invoke(__proj1, *__first1)))
-             return false;
+           for (; __first1 != __last1 && __first2 != __last2;
+                ++__first1, (void) ++__first2)
+             {
+               if (std::__invoke(__comp,
+                                 std::__invoke(__proj1, *__first1),
+                                 std::__invoke(__proj2, *__first2)))
+                 return true;
+               if (std::__invoke(__comp,
+                                 std::__invoke(__proj2, *__first2),
+                                 std::__invoke(__proj1, *__first1)))
+                 return false;
+             }
+           return __first1 == __last1 && __first2 != __last2;
          }
-       return __first1 == __last1 && __first2 != __last2;
       }
 
     template<input_range _Range1, input_range _Range2,
index f8643b5a9332e3bfd1a3dad54d8afd4424677352..cc24483b2d3ff7b173001b29d91ea4448cbee3b2 100644 (file)
@@ -93,11 +93,8 @@ namespace ranges
                         std::__niter_base(std::move(__last2)),
                         std::move(__pred),
                         std::move(__proj1), std::move(__proj2));
-
-       constexpr bool __sized_iters
-         = (sized_sentinel_for<_Sent1, _Iter1>
-            && sized_sentinel_for<_Sent2, _Iter2>);
-       if constexpr (__sized_iters)
+       else if constexpr (sized_sentinel_for<_Sent1, _Iter1>
+                          && sized_sentinel_for<_Sent2, _Iter2>)
          {
            auto __d1 = ranges::distance(__first1, __last1);
            auto __d2 = ranges::distance(__first2, __last2);