-
Notifications
You must be signed in to change notification settings - Fork 458
convert some ::value to _v #10765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
convert some ::value to _v #10765
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,10 +230,7 @@ _CCCL_API void __stable_sort_move( | |
| } | ||
|
|
||
| template <class _Tp> | ||
| struct __stable_sort_switch | ||
| { | ||
| static const unsigned value = 128 * is_trivially_copy_assignable_v<_Tp>; | ||
| }; | ||
| inline constexpr unsigned __stable_sort_switch_v = 128 * is_trivially_copy_assignable_v<_Tp>; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be just a function? |
||
|
|
||
| template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> | ||
| _CCCL_API void __stable_sort( | ||
|
|
@@ -258,7 +255,7 @@ _CCCL_API void __stable_sort( | |
| } | ||
| return; | ||
| } | ||
| if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) | ||
| if (__len <= static_cast<difference_type>(__stable_sort_switch_v<value_type>)) | ||
| { | ||
| ::cuda::std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); | ||
| return; | ||
|
|
@@ -292,7 +289,7 @@ _CCCL_API void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIt | |
| difference_type __len = __last - __first; | ||
| pair<value_type*, ptrdiff_t> __buf(0, 0); | ||
| unique_ptr<value_type, __return_temporary_buffer> __h; | ||
| if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) | ||
| if (__len > static_cast<difference_type>(__stable_sort_switch_v<value_type>)) | ||
| { | ||
| __buf = ::cuda::std::get_temporary_buffer<value_type>(__len); | ||
| __h.reset(__buf.first); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,7 +80,7 @@ template <typename _Range, typename = void> | |
| inline constexpr bool __has_tuple_size_v = false; | ||
|
|
||
| template <typename _Range> | ||
| inline constexpr bool __has_tuple_size_v<_Range, void_t<decltype(tuple_size<remove_cvref_t<_Range>>::value)>> = true; | ||
| inline constexpr bool __has_tuple_size_v<_Range, void_t<decltype(tuple_size_v<remove_cvref_t<_Range>>)>> = true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
for f in \
libcudacxx/include/cuda/std/__simd/utility.h \
libcudacxx/include/cuda/__complex/traits.h \
libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
do
echo "===== $f ====="
wc -l "$f"
sed -n '1,125p' "$f"
done
echo "===== tuple_size and tuple_size_v definitions/usages ====="
rg -n --glob '*.{h,hpp,cpp,cc,cxx,cu,cuh}' \
'tuple_size_v|tuple_size<|__has_tuple_size_v|__is_complex_compatible_tuple_like|__pair_like' \
libcudacxx | head -250
echo "===== current diff summary ====="
git diff --stat -- \
libcudacxx/include/cuda/std/__simd/utility.h \
libcudacxx/include/cuda/__complex/traits.h \
libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
echo "===== current diff for the three files ====="
git diff -- \
libcudacxx/include/cuda/std/__simd/utility.h \
libcudacxx/include/cuda/__complex/traits.h \
libcudacxx/include/cuda/std/__tuple_dir/tuple_like.hRepository: NVIDIA/cccl Length of output: 38810 🏁 Script executed: #!/bin/bash
set -eu
echo "===== tuple_size implementation ====="
cat -n libcudacxx/include/cuda/std/__tuple_dir/tuple_size.h | sed -n '1,115p'
echo "===== constraint macro definitions ====="
rg -n -A18 -B8 \
'_CCCL_REQUIRES_EXPR|define _CCCL_REQUIRES_EXPR|_CCCL_CONCEPT' \
libcudacxx/include/cuda/std/__concepts/concept_macros.h \
libcudacxx/include/cuda/std/__concepts 2>/dev/null | head -220
echo "===== related tuple-like and complex tests ====="
rg -n -A12 -B8 \
'__pair_like|__is_complex_compatible_tuple_like|incomplete|tuple_size_v' \
libcudacxx/test/libcudacxx/cuda/complex \
libcudacxx/test/libcudacxx/std/utilities/tuple/tuple.tuple/tuple.helper \
libcudacxx/test/libcudacxx/std/ranges 2>/dev/null | head -300
echo "===== recent history for the affected files ====="
git log --oneline -12 -- \
libcudacxx/include/cuda/std/__simd/utility.h \
libcudacxx/include/cuda/__complex/traits.h \
libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
echo "===== available C++ compilers ====="
command -v g++ || true
command -v clang++ || true
command -v nvcc || trueRepository: NVIDIA/cccl Length of output: 50367 🏁 Script executed: #!/bin/bash
set -eu
echo "===== available C++ compilers ====="
command -v g++ || true
command -v clang++ || true
command -v nvcc || true
echo "===== focused concept macro sections ====="
sed -n '35,72p;201,225p;229,290p' libcudacxx/include/cuda/std/__concepts/concept_macros.h
echo "===== focused history ====="
git log --oneline -12 -- libcudacxx/include/cuda/std/__simd/utility.h
git log --oneline -12 -- libcudacxx/include/cuda/__complex/traits.h
git log --oneline -12 -- libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
echo "===== commits that introduced the tuple-size spellings ====="
git log --all --oneline -S'tuple_size_v<remove_cvref_t<_Range>>' -- libcudacxx/include/cuda/std/__simd/utility.h || true
git log --all --oneline -S'tuple_size_v<_Tp>' -- libcudacxx/include/cuda/__complex/traits.h || true
git log --all --oneline -S'tuple_size_v<remove_cvref_t<_Tp>>' -- libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h || true
echo "===== standalone compiler probe ====="
cat >/tmp/tuple-size-probe.cpp <<'CPP'
`#include` <cstddef>
`#include` <type_traits>
template <class T>
struct tuple_size;
template <class T>
inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
template <class T, class = void>
inline constexpr bool has_member_probe = false;
template <class T>
inline constexpr bool has_member_probe<T, std::void_t<decltype(tuple_size<T>::value)>> = true;
template <class T, class = void>
inline constexpr bool has_variable_probe = false;
template <class T>
inline constexpr bool has_variable_probe<T, std::void_t<decltype(tuple_size_v<T>)>> = true;
template <class T>
concept variable_constraint = requires { requires(tuple_size_v<T> == 2); };
template <class T>
concept member_constraint = requires { requires(tuple_size<T>::value == 2); };
struct Incomplete;
static_assert(!has_member_probe<Incomplete>);
static_assert(!has_variable_probe<Incomplete>);
static_assert(!member_constraint<Incomplete>);
static_assert(!variable_constraint<Incomplete>);
int main() {}
CPP
if command -v g++ >/dev/null 2>&1; then
g++ -std=c++20 -fsyntax-only /tmp/tuple-size-probe.cpp
echo "g++ probe: success"
fi
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only /tmp/tuple-size-probe.cpp
echo "clang++ probe: success"
fiRepository: NVIDIA/cccl Length of output: 8332 🏁 Script executed: #!/bin/bash
set -u
echo "===== conversion commit ====="
git show --no-ext-diff --format=fuller --stat 8bd263c5e
git show --no-ext-diff --format= --unified=18 8bd263c5e -- \
libcudacxx/include/cuda/std/__simd/utility.h \
libcudacxx/include/cuda/__complex/traits.h \
libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
echo "===== standalone compiler probe with clang++ ====="
cat >/tmp/tuple-size-probe.cpp <<'CPP'
`#include` <cstddef>
`#include` <type_traits>
template <class T>
struct tuple_size;
template <class T>
inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
template <class T, class = void>
inline constexpr bool has_member_probe = false;
template <class T>
inline constexpr bool has_member_probe<T, std::void_t<decltype(tuple_size<T>::value)>> = true;
template <class T, class = void>
inline constexpr bool has_variable_probe = false;
template <class T>
inline constexpr bool has_variable_probe<T, std::void_t<decltype(tuple_size_v<T>)>> = true;
template <class T>
concept variable_constraint = requires { requires(tuple_size_v<T> == 2); };
template <class T>
concept member_constraint = requires { requires(tuple_size<T>::value == 2); };
struct Incomplete;
static_assert(!has_member_probe<Incomplete>);
static_assert(!has_variable_probe<Incomplete>);
static_assert(!member_constraint<Incomplete>);
static_assert(!variable_constraint<Incomplete>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ --version | head -1
clang++ -std=c++20 -fsyntax-only /tmp/tuple-size-probe.cpp
echo "clang++ probe: success"
else
echo "clang++ unavailable"
fiRepository: NVIDIA/cccl Length of output: 8714 🏁 Script executed: #!/bin/bash
set -u
echo "===== _CCCL_REQUIRES_EXPR definition ====="
rg -n -A12 -B8 '_CCCL_REQUIRES_EXPR' libcudacxx/include/cuda/std
echo "===== exact pair-like behavior in a standalone probe ====="
cat >/tmp/pair-like-probe.cpp <<'CPP'
`#include` <cstddef>
template <class T>
struct tuple_size;
template <class T>
inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
template <class T>
inline constexpr bool tuple_like_ext = false;
template <class T>
concept pair_like_variable = requires {
requires(tuple_like_ext<T>);
requires(tuple_size_v<T> == 2);
};
template <class T>
concept pair_like_member = requires {
requires(tuple_like_ext<T>);
requires(tuple_size<T>::value == 2);
};
struct Unsupported;
static_assert(!pair_like_variable<Unsupported>);
static_assert(!pair_like_member<Unsupported>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only /tmp/pair-like-probe.cpp
rc=$?
echo "clang++ pair-like probe exit: $rc"
fi
echo "===== exact complex-style behavior in a standalone probe ====="
cat >/tmp/complex-like-probe.cpp <<'CPP'
`#include` <cstddef>
`#include` <type_traits>
template <class T>
struct tuple_size;
template <class T>
inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
template <class T>
using tuple_element_t = typename T::missing;
template <class T>
concept complex_like_variable = requires {
requires(tuple_size_v<T> == 2);
requires(std::is_same_v<tuple_element_t<T>, tuple_element_t<T>>);
};
template <class T>
concept complex_like_member = requires {
requires(tuple_size<T>::value == 2);
requires(std::is_same_v<tuple_element_t<T>, tuple_element_t<T>>);
};
struct Unsupported;
static_assert(!complex_like_variable<Unsupported>);
static_assert(!complex_like_member<Unsupported>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only /tmp/complex-like-probe.cpp
rc=$?
echo "clang++ complex-like probe exit: $rc"
fiRepository: NVIDIA/cccl Length of output: 50368 🏁 Script executed: #!/bin/bash
set -u
echo "===== _CCCL_REQUIRES_EXPR implementation ====="
sed -n '296,322p' libcudacxx/include/cuda/std/__concepts/concept_macros.h
echo "===== pair-like probe with a recognized but incomplete tuple type ====="
cat >/tmp/pair-like-probe.cpp <<'CPP'
`#include` <cstddef>
template <class T>
struct tuple_size;
template <class T>
inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;
struct RecognizedTuple;
template <>
inline constexpr bool tuple_like_ext<RecognizedTuple> = true;
template <class T>
concept pair_like_variable = requires {
requires(tuple_like_ext<T>);
requires(tuple_size_v<T> == 2);
};
template <class T>
concept pair_like_member = requires {
requires(tuple_like_ext<T>);
requires(tuple_size<T>::value == 2);
};
static_assert(!pair_like_member<RecognizedTuple>);
static_assert(!pair_like_variable<RecognizedTuple>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only /tmp/pair-like-probe.cpp >/tmp/pair-like-probe.out 2>&1
rc=$?
echo "clang++ pair-like probe exit: $rc"
sed -n '1,25p' /tmp/pair-like-probe.out
fi
echo "===== direct current-header probes ====="
cat >/tmp/current-header-probe.cpp <<'CPP'
`#include` <cuda/std/__simd/utility.h>
`#include` <cuda/std/__tuple_dir/tuple_like.h>
`#include` <cuda/__complex/traits.h>
struct UnsupportedTuple;
static_assert(!::cuda::std::simd::__has_tuple_size_v<UnsupportedTuple>);
static_assert(!::cuda::std::__pair_like<UnsupportedTuple>);
static_assert(!::cuda::__is_complex_compatible_tuple_like<UnsupportedTuple>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only -Ilibcudacxx/include /tmp/current-header-probe.cpp \
>/tmp/current-header-probe.out 2>&1
rc=$?
echo "clang++ current-header probe exit: $rc"
sed -n '1,45p' /tmp/current-header-probe.out
fiRepository: NVIDIA/cccl Length of output: 7470 🏁 Script executed: #!/bin/bash
set -u
echo "===== direct __pair_like probe with an incomplete recognized tuple ====="
cat >/tmp/pair-like-current-probe.cpp <<'CPP'
`#include` <cuda/std/__tuple_dir/tuple_like.h>
static_assert(!::cuda::std::__pair_like<::cuda::std::tuple<int, int>>);
int main() {}
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only -Ilibcudacxx/include \
/tmp/pair-like-current-probe.cpp >/tmp/pair-like-current-probe.out 2>&1
rc=$?
echo "clang++ __pair_like probe exit: $rc"
sed -n '1,40p' /tmp/pair-like-current-probe.out
fi
echo "===== parent implementation of all three probes ====="
git show 8bd263c5e^:libcudacxx/include/cuda/std/__simd/utility.h | sed -n '78,86p'
git show 8bd263c5e^:libcudacxx/include/cuda/__complex/traits.h | sed -n '37,44p'
git show 8bd263c5e^:libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h | sed -n '93,99p'Repository: NVIDIA/cccl Length of output: 4870 critical: Restore member-based tuple-size probes in all three constraint paths.
📍 Affects 3 files
Source: Path instructions
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to be reverted |
||
|
|
||
| template <typename _Range, typename = void> | ||
| inline constexpr bool __has_static_extent_v = false; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -94,7 +94,7 @@ _CCCL_CONCEPT __tuple_like = __tuple_like_ext<remove_cvref_t<_Tp>>; | |
| // Not on line 74 because of __COUNTER__ missing in NVRTC | ||
| template <class _Tp> | ||
| _CCCL_CONCEPT __pair_like = _CCCL_REQUIRES_EXPR((_Tp)) // | ||
| (requires(__tuple_like<_Tp>), requires(tuple_size<remove_cvref_t<_Tp>>::value == 2)); | ||
| (requires(__tuple_like<_Tp>), requires(tuple_size_v<remove_cvref_t<_Tp>> == 2)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- tuple_like.h ---'
sed -n '70,115p' libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
printf '%s\n' '--- concept macros ---'
sed -n '1,240p' libcudacxx/include/cuda/std/__concepts/concept_macros.h
printf '%s\n' '--- related tuple_size_v usage ---'
rg -n -C 3 'tuple_size_v|__pair_like|_CCCL_REQUIRES_EXPR' libcudacxx/include/cuda/std/__tuple_dir libcudacxx/include/cuda/std/__conceptsRepository: NVIDIA/cccl Length of output: 31007 🏁 Script executed: #!/bin/bash
set -eu
sed -n '365,395p' libcudacxx/include/cuda/std/__concepts/concept_macros.h
sed -n '1,90p' libcudacxx/include/cuda/std/__tuple_dir/tuple_size.h
sed -n '1,78p' libcudacxx/include/cuda/std/__tuple_dir/tuple_like.h
git diff -- libcudacxx/include/cuda/std/__tuple_dir/tuple_like.hRepository: NVIDIA/cccl Length of output: 7520 🏁 Script executed: #!/bin/bash
set -eu
sed -n '210,295p' libcudacxx/include/cuda/std/__concepts/concept_macros.h
command -v g++ || true
command -v clang++ || true
python3 - <<'PY'
from pathlib import Path
p = Path("libcudacxx/include/cuda/std/__concepts/concept_macros.h")
text = p.read_text()
for name in ("_CCCL_CONCEPT_REQUIREMENT_CASE__CCCL_SWITCH_REQUIRES",
"_CCCL_CONCEPT_REQUIREMENT_0",
"_CCCL_CONCEPT_REQUIREMENT_1"):
print(name, text.find(name))
PY
cat >/tmp/tuple_size_probe.cpp <<'CPP'
`#include` <type_traits>
template<class> struct tuple_size;
template<class T> inline constexpr int tuple_size_v = tuple_size<T>::value;
template<class T>
concept member_form = requires {
requires (std::is_same_v<T, int>);
requires (tuple_size<T>::value == 2);
};
template<class T>
concept variable_form = requires {
requires (std::is_same_v<T, int>);
requires (tuple_size_v<T> == 2);
};
static_assert(!member_form<int>);
static_assert(!variable_form<int>);
CPP
if command -v g++ >/dev/null 2>&1; then
g++ -std=c++20 -fsyntax-only /tmp/tuple_size_probe.cpp
fi
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++20 -fsyntax-only /tmp/tuple_size_probe.cpp
fiRepository: NVIDIA/cccl Length of output: 5471 🏁 Script executed: #!/bin/bash
set -u
cat >/tmp/cccl_fallback_probe.cpp <<'CPP'
template<bool>
struct select {};
template<>
struct select<true> {
template<class T>
using type = T;
};
template<bool B, class T = void>
using enable_if_t = typename select<B>::template type<T>;
template<class> struct tuple_size;
template<class T>
inline constexpr int tuple_size_v = tuple_size<T>::value;
template<bool B, enable_if_t<B, int> = 0>
inline constexpr int requires_value = 0;
template<class T>
inline constexpr bool tuple_like = false;
template<class T>
struct member_form {
template<class U>
static auto check()
-> enable_if_t<
(decltype(requires_value<tuple_like<U>>{}),
decltype(requires_value<(tuple_size<U>::value == 2)>{}),
true),
void>;
};
template<class T>
struct variable_form {
template<class U>
static auto check()
-> enable_if_t<
(decltype(requires_value<tuple_like<U>>{}),
decltype(requires_value<(tuple_size_v<U> == 2)>{}),
true),
void>;
};
template<class T, class = void>
struct has_member : false {};
template<class T>
struct has_member<T, decltype(member_form<T>::template check<T>())> : true {};
template<class T, class = void>
struct has_variable : false {};
template<class T>
struct has_variable<T, decltype(variable_form<T>::template check<T>())> : true {};
static_assert(!has_member<int>::value);
static_assert(!has_variable<int>::value);
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++17 -fsyntax-only /tmp/cccl_fallback_probe.cpp
printf '%s\n' 'clang probe: passed'
else
printf '%s\n' 'clang++ unavailable'
fi
if command -v g++ >/dev/null 2>&1; then
if g++ -std=c++17 -fsyntax-only /tmp/cccl_fallback_probe.cpp; then
printf '%s\n' 'g++ probe: passed'
else
printf '%s\n' 'g++ probe: unavailable or failed'
fi
fiRepository: NVIDIA/cccl Length of output: 2675 🏁 Script executed: #!/bin/bash
set -eu
cat >/tmp/cccl_fallback_probe.cpp <<'CPP'
template<bool>
struct select {};
template<>
struct select<true> {
template<class T>
using type = T;
};
template<bool B, class T = void>
using enable_if_t = typename select<B>::template type<T>;
template<class> struct tuple_size;
template<class T>
inline constexpr int tuple_size_v = tuple_size<T>::value;
template<bool B, enable_if_t<B, int> = 0>
inline constexpr int requires_value = 0;
template<class T>
inline constexpr bool tuple_like = false;
template<class T>
struct member_form {
template<class U>
static auto check()
-> decltype(
requires_value<tuple_like<U>>,
requires_value<(tuple_size<U>::value == 2)>,
void());
};
template<class T>
struct variable_form {
template<class U>
static auto check()
-> decltype(
requires_value<tuple_like<U>>,
requires_value<(tuple_size_v<U> == 2)>,
void());
};
template<class T, class = void>
struct has_member { static constexpr bool value = false; };
template<class T>
struct has_member<T, decltype(member_form<T>::template check<T>())> {
static constexpr bool value = true;
};
template<class T, class = void>
struct has_variable { static constexpr bool value = false; };
template<class T>
struct has_variable<T, decltype(variable_form<T>::template check<T>())> {
static constexpr bool value = true;
};
static_assert(!has_member<int>::value);
static_assert(!has_variable<int>::value);
CPP
if command -v clang++ >/dev/null 2>&1; then
clang++ -std=c++17 -fsyntax-only /tmp/cccl_fallback_probe.cpp
printf '%s\n' 'clang probe: passed'
else
printf '%s\n' 'clang++ unavailable'
fi
if command -v g++ >/dev/null 2>&1; then
g++ -std=c++17 -fsyntax-only /tmp/cccl_fallback_probe.cpp
printf '%s\n' 'g++ probe: passed'
else
printf '%s\n' 'g++ unavailable'
fiRepository: NVIDIA/cccl Length of output: 271 🌐 Web query:
💡 Result: The issue where std::tuple_size_v causes a compilation error (a hard error) instead of a SFINAE substitution failure arises because the evaluation of the variable template's initializer—std::tuple_size::value—often occurs outside the immediate context of a template substitution [1][2][3]. Under C++ template instantiation rules, SFINAE (Substitution Failure Is Not An Error) only applies to errors occurring within the immediate context of a function signature or template parameter list [2]. When you use std::tuple_size_v, the compiler must instantiate the variable template specialization to determine its value. If the type T is not tuple-like, this instantiation triggers an error in the initializer (std::tuple_size::value). Because this instantiation is considered a side effect of the template substitution rather than an error in the immediate context, the compiler treats it as a hard error [1][2]. In contrast, using std::tuple_size::value directly is often SFINAE-friendly because the failure to find a::value member in the primary template—which is typically undefined—occurs in a context where the compiler can gracefully treat it as a substitution failure [3][4]. For NVCC and NVRTC users, this behavior is a standard C++ language compliance issue rather than a specific toolchain bug [5][3]. When working with CUDA libraries (such as libcu++), encountering this error usually means: 1. The type T passed to tuple_size_v does not meet the requirements of a "tuple-like" type (it lacks an appropriate std::tuple_size specialization) [4]. 2. You are attempting to use it in a SFINAE-constrained context (like a requires clause or std::enable_if) where you expect failure to be silent, but the compiler is forcing an instantiation [2][6][3]. To resolve this, you can: - Use std::tuple_size::value instead of the variable template std::tuple_size_v [5][3]. - If you must use a variable template, wrap it in a custom trait that inherits from std::integral_constant to ensure the failure occurs in a way that respects SFINAE, or define a primary template specialization for your custom types to ensure std::tuple_size::value is always valid [6][4]. Citations:
important: Preserve the member-based check for non-concepts toolchains. Source: Path instructions |
||
|
|
||
| _CCCL_END_NAMESPACE_CUDA_STD | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ is_copy_assignable : public is_assignable<add_lvalue_reference_t<_Tp>, add_lvalu | |
|
|
||
| template <class _Tp> | ||
| inline constexpr bool is_copy_assignable_v = | ||
| is_assignable<add_lvalue_reference_t<_Tp>, add_lvalue_reference_t<add_const_t<_Tp>>>::value; | ||
| is_assignable_v<add_lvalue_reference_t<_Tp>, add_lvalue_reference_t<add_const_t<_Tp>>>; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kind of funny, because its a pessimization in this context. The point here is that there is no builtin available, so |
||
|
|
||
| #endif // No builtin | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was intentional,
tuple_size_vdidn't get the job doneThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we cannot do that.
tuple_sizeis one of the places where we need to keep it like that