PR libstdc++/83607 specialize Boyer-Moore searchers for std::byte
authorJonathan Wakely <jwakely@redhat.com>
Thu, 4 Jan 2018 10:21:29 +0000 (10:21 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 4 Jan 2018 10:21:29 +0000 (10:21 +0000)
PR libstdc++/83607
* include/std/functional (__is_byte_like): New trait.
(__is_std_equal_to): Remove.
(__boyer_moore_base_t): Use __is_byte_like instead of
__is_std_equal_to.
* include/experimental/functional (__is_std_equal_to): Remove.
(__boyer_moore_base_t): Use __is_byte_like instead of
__is_std_equal_to.
* testsuite/20_util/function_objects/83607.cc: New test.

From-SVN: r256231

libstdc++-v3/ChangeLog
libstdc++-v3/include/experimental/functional
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/20_util/function_objects/83607.cc [new file with mode: 0644]

index 64fa7204d84e147c187f9723e6c10d2ddd1170e1..1fca54f212df7ea9daa2335dcd8bcc0a0653178c 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-04  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/83607
+       * include/std/functional (__is_byte_like): New trait.
+       (__is_std_equal_to): Remove.
+       (__boyer_moore_base_t): Use __is_byte_like instead of
+       __is_std_equal_to.
+       * include/experimental/functional (__is_std_equal_to): Remove.
+       (__boyer_moore_base_t): Use __is_byte_like instead of
+       __is_std_equal_to.
+       * testsuite/20_util/function_objects/83607.cc: New test.
+
 2018-01-03  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        Protect optional's deduction guide with the feature macro
index 950f89cfc317bebaf80715f8647df546afb19ad1..de68c802661c1040cb87b7cf166159d53f5ffcf1 100644 (file)
@@ -157,20 +157,13 @@ inline namespace fundamentals_v1
       std::tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char;
     };
 
-  template<typename _Pred>
-    struct __is_std_equal_to : std::false_type { };
-
-  template<>
-    struct __is_std_equal_to<std::equal_to<void>> : std::true_type { };
-
   // Use __boyer_moore_array_base when pattern consists of narrow characters
-  // and uses std::equal_to as the predicate.
+  // (or std::byte) and uses std::equal_to as the predicate.
   template<typename _RAIter, typename _Hash, typename _Pred,
            typename _Val = typename iterator_traits<_RAIter>::value_type,
           typename _Diff = typename iterator_traits<_RAIter>::difference_type>
     using __boyer_moore_base_t
-      = std::conditional_t<sizeof(_Val) == 1 && is_integral<_Val>::value
-                          && __is_std_equal_to<_Pred>::value,
+      = std::conditional_t<std::__is_byte_like<_Val, _Pred>::value,
                           __boyer_moore_array_base<_Diff, 256, _Pred>,
                           __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>;
 
index 1175deb65975d53462bed4d69eb779c14f18004e..2b46ba899dd0d981893d212a6bb34a4d8569e0e4 100644 (file)
@@ -879,7 +879,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Fn _M_fn;
     };
 
-#if __cplusplus > 201402L
+  template<typename _Tp, typename _Pred>
+    struct __is_byte_like : false_type { };
+
+  template<typename _Tp>
+    struct __is_byte_like<_Tp, equal_to<_Tp>>
+    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };
+
+  template<typename _Tp>
+    struct __is_byte_like<_Tp, equal_to<void>>
+    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };
+
+#if __cplusplus >= 201703L
+  // Declare std::byte (full definition is in <cstddef>).
+  enum class byte : unsigned char;
+
+  template<>
+    struct __is_byte_like<byte, equal_to<byte>>
+    : true_type { };
+
+  template<>
+    struct __is_byte_like<byte, equal_to<void>>
+    : true_type { };
+
 #define __cpp_lib_not_fn 201603
   /// [func.not_fn] Function template not_fn
   template<typename _Fn>
@@ -988,20 +1010,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char;
     };
 
-  template<typename _Pred>
-    struct __is_std_equal_to : false_type { };
-
-  template<>
-    struct __is_std_equal_to<equal_to<void>> : true_type { };
-
   // Use __boyer_moore_array_base when pattern consists of narrow characters
-  // and uses std::equal_to as the predicate.
+  // (or std::byte) and uses std::equal_to as the predicate.
   template<typename _RAIter, typename _Hash, typename _Pred,
            typename _Val = typename iterator_traits<_RAIter>::value_type,
           typename _Diff = typename iterator_traits<_RAIter>::difference_type>
     using __boyer_moore_base_t
-      = conditional_t<sizeof(_Val) == 1 && is_integral<_Val>::value
-                     && __is_std_equal_to<_Pred>::value,
+      = conditional_t<__is_byte_like<_Val, _Pred>::value,
                      __boyer_moore_array_base<_Diff, 256, _Pred>,
                      __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>;
 
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/83607.cc b/libstdc++-v3/testsuite/20_util/function_objects/83607.cc
new file mode 100644 (file)
index 0000000..a752ca7
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <functional>
+#include <cstddef>
+
+// PR libstdc++/83607
+
+using std::boyer_moore_searcher;
+using std::boyer_moore_horspool_searcher;
+using std::byte;
+using std::hash;
+using std::equal_to;
+
+void
+test01()
+{
+  constexpr auto expected = sizeof(boyer_moore_searcher<const char*>);
+  static_assert(sizeof(boyer_moore_searcher<const long*>) != expected);
+  using T1 = boyer_moore_searcher<char*, hash<char>, equal_to<char>>;
+  static_assert(sizeof(T1) == expected);
+  using T2 = boyer_moore_searcher<byte*>;
+  static_assert(sizeof(T2) == expected);
+  using T3 = boyer_moore_searcher<const byte*>;
+  static_assert(sizeof(T3) == expected);
+  using T4 = boyer_moore_searcher<const byte*, hash<byte>, equal_to<byte>>;
+  static_assert(sizeof(T4) == expected);
+}
+
+void
+test02()
+{
+  constexpr auto expected = sizeof(boyer_moore_horspool_searcher<const char*>);
+  static_assert(sizeof(boyer_moore_horspool_searcher<const long*>) != expected);
+  using T1 = boyer_moore_horspool_searcher<char*, hash<char>, equal_to<char>>;
+  static_assert(sizeof(T1) == expected);
+  using T2 = boyer_moore_horspool_searcher<byte*>;
+  static_assert(sizeof(T2) == expected);
+  using T3 = boyer_moore_horspool_searcher<const byte*>;
+  static_assert(sizeof(T3) == expected);
+  using T4
+    = boyer_moore_horspool_searcher<const byte*, hash<byte>, equal_to<byte>>;
+  static_assert(sizeof(T4) == expected);
+}