[libcxx-commits] [PATCH] D72708: [libc++] Make sure std::is_object returns true for block types

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 14 08:12:29 PST 2020


ldionne created this revision.
ldionne added reviewers: dexonsmith, EricWF, mclow.lists.
Herald added subscribers: libcxx-commits, jkorous, christof.
Herald added a project: libc++.

This allows blocks to be used in more places, for example in std::optional.

rdar://problem/57892832


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72708

Files:
  libcxx/include/__config
  libcxx/include/type_traits
  libcxx/test/libcxx/type_traits/is_object.objc.pass.mm


Index: libcxx/test/libcxx/type_traits/is_object.objc.pass.mm
===================================================================
--- /dev/null
+++ libcxx/test/libcxx/type_traits/is_object.objc.pass.mm
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03
+
+// <type_traits>
+
+// std::is_object
+
+// Make sure we report that blocks are object types.
+
+#include <type_traits>
+
+struct Foo { };
+template <int> struct Arg { };
+
+static_assert(std::is_object<void (^)(void)>::value, "");
+static_assert(std::is_object<void (^)()>::value, "");
+static_assert(std::is_object<void (^)(Arg<0>)>::value, "");
+static_assert(std::is_object<void (^)(Arg<0>, Arg<1>)>::value, "");
+static_assert(std::is_object<void (^)(Arg<0>, Arg<1>, Arg<2>)>::value, "");
+static_assert(std::is_object<Foo (^)(void)>::value, "");
+static_assert(std::is_object<Foo (^)()>::value, "");
+static_assert(std::is_object<Foo (^)(Arg<0>)>::value, "");
+static_assert(std::is_object<Foo (^)(Arg<0>, Arg<1>)>::value, "");
+static_assert(std::is_object<Foo (^)(Arg<0>, Arg<1>, Arg<2>)>::value, "");
+
+int main(int, char**) {
+    return 0;
+}
Index: libcxx/include/type_traits
===================================================================
--- libcxx/include/type_traits
+++ libcxx/include/type_traits
@@ -1031,13 +1031,19 @@
     = is_scalar<_Tp>::value;
 #endif
 
+template <class _Tp> struct __is_block : false_type {};
+#if defined(_LIBCPP_HAS_OBJC_BLOCKS)
+template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
+#endif
+
 // is_object
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
     : public integral_constant<bool, is_scalar<_Tp>::value ||
                                      is_array<_Tp>::value  ||
                                      is_union<_Tp>::value  ||
-                                     is_class<_Tp>::value  > {};
+                                     is_class<_Tp>::value  ||
+                                     __is_block<_Tp>::value > {};
 
 #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 template <class _Tp>
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -463,6 +463,10 @@
 #define _LIBCPP_HAS_OBJC_ARC_WEAK
 #endif
 
+#if __has_extension(blocks)
+#  define _LIBCPP_HAS_OBJC_BLOCKS
+#endif
+
 #if !(__has_feature(cxx_relaxed_constexpr))
 #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
 #endif


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72708.237982.patch
Type: text/x-patch
Size: 2856 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200114/4c571008/attachment-0001.bin>


More information about the libcxx-commits mailing list