[libcxx-commits] [libcxx] [libc++][ranges] add static_assert for ranges::to (PR #135802)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Apr 15 09:07:51 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Yuzhiy (Yuzhiy05)
<details>
<summary>Changes</summary>
add static_assert using is_class_v and is_union_v to reject no-class type template parameter and test for this
Close #<!-- -->132133
@<!-- -->frederick-vs-ja
Sorry for the delayed response on the previous PR —I spent some time learning how to build libc++ and run its tests. I’ve written a test referencing the `to.static_assert.verify.cpp` file in the same directory, but it fails to compile. I have two questions:
Why does a test expecting a failed static assertion pass in lit?
What might be wrong with my test implementation?
---
Full diff: https://github.com/llvm/llvm-project/pull/135802.diff
2 Files Affected:
- (modified) libcxx/include/__ranges/to.h (+4-2)
- (added) libcxx/test/libcxx/ranges/range.utility/range.utility.conv/to.verfiy.cpp (+17)
``````````diff
diff --git a/libcxx/include/__ranges/to.h b/libcxx/include/__ranges/to.h
index c937b0656de87..2adae5e0edbfb 100644
--- a/libcxx/include/__ranges/to.h
+++ b/libcxx/include/__ranges/to.h
@@ -28,6 +28,8 @@
#include <__type_traits/add_pointer.h>
#include <__type_traits/is_const.h>
#include <__type_traits/is_volatile.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_union.h>
#include <__type_traits/type_identity.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
@@ -81,7 +83,7 @@ template <class _Container, input_range _Range, class... _Args>
static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
static_assert(
!is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
-
+ static_assert(is_class_v<_Container>||is_union_v<_Container>, "The target must be a class type");
// First see if the non-recursive case applies -- the conversion target is either:
// - a range with a convertible value type;
// - a non-range type which might support being created from the input argument(s) (e.g. an `optional`).
@@ -208,7 +210,7 @@ template <class _Container, class... _Args>
static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
static_assert(
!is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
-
+ static_assert(is_class_v<_Container>||is_union_v<_Container>, "The target must be a class type");
auto __to_func = []<input_range _Range, class... _Tail>(_Range&& __range, _Tail&&... __tail) static
requires requires { //
/**/ ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
diff --git a/libcxx/test/libcxx/ranges/range.utility/range.utility.conv/to.verfiy.cpp b/libcxx/test/libcxx/ranges/range.utility/range.utility.conv/to.verfiy.cpp
new file mode 100644
index 0000000000000..9ff01b10a759d
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.utility/range.utility.conv/to.verfiy.cpp
@@ -0,0 +1,17 @@
+#include <ranges>
+
+
+
+void test(){
+ struct R {
+ int* begin() const{reurn nullptr;};
+ int* end() const{return nullptr;};
+
+ operator int() const { return 0; }
+ };
+ (void)std::ranges::to<int>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<int>());
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+
+}
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/135802
More information about the libcxx-commits
mailing list