CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
512 lines
15 KiB
C++
512 lines
15 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// cuda::std::ranges::end
|
|
// cuda::std::ranges::cend
|
|
|
|
#include <cuda/std/cassert>
|
|
#include <cuda/std/ranges>
|
|
#include <cuda/std/utility>
|
|
|
|
#include "test_iterators.h"
|
|
#include "test_macros.h"
|
|
|
|
using RangeEndT = decltype(cuda::std::ranges::end);
|
|
using RangeCEndT = decltype(cuda::std::ranges::cend);
|
|
|
|
TEST_GLOBAL_VARIABLE int globalBuff[8] = {};
|
|
|
|
#if !TEST_COMPILER(MSVC, <, 19, 23)
|
|
// old MSVC has a bug where it doesn't properly handle rvalue arrays
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, int (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, int (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, int (&&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, int (&&)[10]>, "");
|
|
#endif // !TEST_COMPILER(MSVC, <, 19, 23)
|
|
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, int (&)[]>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, int (&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, int (&)[]>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCEndT, int (&)[10]>, "");
|
|
|
|
struct Incomplete;
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, Incomplete (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, Incomplete (&&)[42]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, Incomplete (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, Incomplete (&&)[42]>, "");
|
|
|
|
struct EndMember
|
|
{
|
|
int x;
|
|
__host__ __device__ const int* begin() const;
|
|
__host__ __device__ constexpr const int* end() const
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
|
|
// Ensure that we can't call with rvalues with borrowing disabled.
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, EndMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndMember&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, EndMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndMember const&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCEndT, EndMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, EndMember&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCEndT, EndMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, EndMember const&&>, "");
|
|
|
|
struct Different
|
|
{
|
|
__host__ __device__ char* begin();
|
|
__host__ __device__ sentinel_wrapper<char*>& end();
|
|
__host__ __device__ short* begin() const;
|
|
__host__ __device__ sentinel_wrapper<short*>& end() const;
|
|
};
|
|
__host__ __device__ constexpr bool testReturnTypes()
|
|
{
|
|
{
|
|
int* x[2] = {};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::end(x)), int**>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cend(x)), int* const*>, "");
|
|
}
|
|
{
|
|
int x[2][2] = {};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::end(x)), int(*)[2]>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cend(x)), const int(*)[2]>, "");
|
|
}
|
|
{
|
|
Different x{};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::end(x)), sentinel_wrapper<char*>>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cend(x)), sentinel_wrapper<short*>>, "");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
__host__ __device__ constexpr bool testArray()
|
|
{
|
|
int a[2] = {};
|
|
assert(cuda::std::ranges::end(a) == a + 2);
|
|
assert(cuda::std::ranges::cend(a) == a + 2);
|
|
|
|
int b[2][2] = {};
|
|
assert(cuda::std::ranges::end(b) == b + 2);
|
|
assert(cuda::std::ranges::cend(b) == b + 2);
|
|
|
|
EndMember c[2] = {};
|
|
assert(cuda::std::ranges::end(c) == c + 2);
|
|
assert(cuda::std::ranges::cend(c) == c + 2);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct EndMemberReturnsInt
|
|
{
|
|
__host__ __device__ int begin() const;
|
|
__host__ __device__ int end() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndMemberReturnsInt const&>, "");
|
|
|
|
struct EndMemberReturnsVoidPtr
|
|
{
|
|
__host__ __device__ const void* begin() const;
|
|
__host__ __device__ const void* end() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndMemberReturnsVoidPtr const&>, "");
|
|
|
|
struct PtrConvertible
|
|
{
|
|
__host__ __device__ operator int*() const;
|
|
};
|
|
struct PtrConvertibleEndMember
|
|
{
|
|
__host__ __device__ PtrConvertible begin() const;
|
|
__host__ __device__ PtrConvertible end() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, PtrConvertibleEndMember const&>, "");
|
|
|
|
struct NoBeginMember
|
|
{
|
|
__host__ __device__ constexpr const int* end();
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, NoBeginMember const&>, "");
|
|
|
|
struct NonConstEndMember
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr int* begin()
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ constexpr int* end()
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, NonConstEndMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, NonConstEndMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, NonConstEndMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, NonConstEndMember const&>, "");
|
|
|
|
struct EnabledBorrowingEndMember
|
|
{
|
|
__host__ __device__ constexpr int* begin() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ constexpr int* end() const
|
|
{
|
|
return &globalBuff[0];
|
|
}
|
|
};
|
|
namespace cuda
|
|
{
|
|
namespace std
|
|
{
|
|
namespace ranges
|
|
{
|
|
template <>
|
|
_CCCL_INLINE_VAR constexpr bool enable_borrowed_range<EnabledBorrowingEndMember> = true;
|
|
}
|
|
} // namespace std
|
|
} // namespace cuda
|
|
struct EndMemberFunction
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr const int* begin() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ constexpr const int* end() const
|
|
{
|
|
return &x;
|
|
}
|
|
__host__ __device__ friend constexpr int* end(EndMemberFunction const&);
|
|
};
|
|
|
|
struct Empty
|
|
{};
|
|
struct EmptyEndMember
|
|
{
|
|
__host__ __device__ Empty begin() const;
|
|
__host__ __device__ Empty end() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EmptyEndMember const&>, "");
|
|
|
|
struct EmptyPtrEndMember
|
|
{
|
|
Empty x;
|
|
__host__ __device__ constexpr const Empty* begin() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ constexpr const Empty* end() const
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
|
|
__host__ __device__ constexpr bool testEndMember()
|
|
{
|
|
EndMember a{};
|
|
assert(cuda::std::ranges::end(a) == &a.x);
|
|
assert(cuda::std::ranges::cend(a) == &a.x);
|
|
|
|
NonConstEndMember b{};
|
|
assert(cuda::std::ranges::end(b) == &b.x);
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, decltype((b))>, "");
|
|
|
|
EnabledBorrowingEndMember c{};
|
|
assert(cuda::std::ranges::end(cuda::std::move(c)) == &globalBuff[0]);
|
|
assert(cuda::std::ranges::cend(cuda::std::move(c)) == &globalBuff[0]);
|
|
|
|
EndMemberFunction d{};
|
|
assert(cuda::std::ranges::end(d) == &d.x);
|
|
assert(cuda::std::ranges::cend(d) == &d.x);
|
|
|
|
EmptyPtrEndMember e{};
|
|
assert(cuda::std::ranges::end(e) == &e.x);
|
|
assert(cuda::std::ranges::cend(e) == &e.x);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct EndFunction
|
|
{
|
|
int x;
|
|
__host__ __device__ friend constexpr const int* begin(EndFunction const&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr const int* end(EndFunction const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, EndFunction const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunction&&>, "");
|
|
|
|
static_assert(cuda::std::is_invocable_v<RangeEndT, EndFunction const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunction&&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunction&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCEndT, EndFunction const&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCEndT, EndFunction&>, "");
|
|
|
|
struct EndFunctionReturnsInt
|
|
{
|
|
__host__ __device__ friend constexpr int begin(EndFunctionReturnsInt const&);
|
|
__host__ __device__ friend constexpr int end(EndFunctionReturnsInt const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunctionReturnsInt const&>, "");
|
|
|
|
struct EndFunctionReturnsVoidPtr
|
|
{
|
|
__host__ __device__ friend constexpr void* begin(EndFunctionReturnsVoidPtr const&);
|
|
__host__ __device__ friend constexpr void* end(EndFunctionReturnsVoidPtr const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunctionReturnsVoidPtr const&>, "");
|
|
|
|
struct EndFunctionReturnsEmpty
|
|
{
|
|
__host__ __device__ friend constexpr Empty begin(EndFunctionReturnsEmpty const&);
|
|
__host__ __device__ friend constexpr Empty end(EndFunctionReturnsEmpty const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunctionReturnsEmpty const&>, "");
|
|
|
|
struct EndFunctionReturnsPtrConvertible
|
|
{
|
|
__host__ __device__ friend constexpr PtrConvertible begin(EndFunctionReturnsPtrConvertible const&);
|
|
__host__ __device__ friend constexpr PtrConvertible end(EndFunctionReturnsPtrConvertible const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, EndFunctionReturnsPtrConvertible const&>, "");
|
|
|
|
struct NoBeginFunction
|
|
{
|
|
__host__ __device__ friend constexpr const int* end(NoBeginFunction const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, NoBeginFunction const&>, "");
|
|
|
|
struct EndFunctionByValue
|
|
{
|
|
__host__ __device__ friend constexpr int* begin(EndFunctionByValue)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr int* end(EndFunctionByValue)
|
|
{
|
|
return &globalBuff[1];
|
|
}
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, EndFunctionByValue>, "");
|
|
|
|
struct EndFunctionEnabledBorrowing
|
|
{
|
|
__host__ __device__ friend constexpr int* begin(EndFunctionEnabledBorrowing)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr int* end(EndFunctionEnabledBorrowing)
|
|
{
|
|
return &globalBuff[2];
|
|
}
|
|
};
|
|
namespace cuda
|
|
{
|
|
namespace std
|
|
{
|
|
namespace ranges
|
|
{
|
|
template <>
|
|
_CCCL_INLINE_VAR constexpr bool enable_borrowed_range<EndFunctionEnabledBorrowing> = true;
|
|
}
|
|
} // namespace std
|
|
} // namespace cuda
|
|
|
|
struct EndFunctionReturnsEmptyPtr
|
|
{
|
|
Empty x;
|
|
__host__ __device__ friend constexpr const Empty* begin(EndFunctionReturnsEmptyPtr const&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr const Empty* end(EndFunctionReturnsEmptyPtr const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
struct EndFunctionWithDataMember
|
|
{
|
|
int x;
|
|
int end;
|
|
__host__ __device__ friend constexpr const int* begin(EndFunctionWithDataMember const&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr const int* end(EndFunctionWithDataMember const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
struct EndFunctionWithPrivateEndMember
|
|
{
|
|
int y;
|
|
__host__ __device__ friend constexpr const int* begin(EndFunctionWithPrivateEndMember const&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr const int* end(EndFunctionWithPrivateEndMember const& bf)
|
|
{
|
|
return &bf.y;
|
|
}
|
|
|
|
private:
|
|
__host__ __device__ const int* end() const;
|
|
};
|
|
|
|
struct BeginMemberEndFunction
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr const int* begin() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
__host__ __device__ friend constexpr const int* end(BeginMemberEndFunction const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
__host__ __device__ constexpr bool testEndFunction()
|
|
{
|
|
const EndFunction a{};
|
|
assert(cuda::std::ranges::end(a) == &a.x);
|
|
assert(cuda::std::ranges::cend(a) == &a.x);
|
|
EndFunction aa{};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, decltype((aa))>, "");
|
|
assert(cuda::std::ranges::cend(aa) == &aa.x);
|
|
|
|
EndFunctionByValue b{};
|
|
assert(cuda::std::ranges::end(b) == &globalBuff[1]);
|
|
assert(cuda::std::ranges::cend(b) == &globalBuff[1]);
|
|
|
|
EndFunctionEnabledBorrowing c{};
|
|
assert(cuda::std::ranges::end(cuda::std::move(c)) == &globalBuff[2]);
|
|
assert(cuda::std::ranges::cend(cuda::std::move(c)) == &globalBuff[2]);
|
|
|
|
const EndFunctionReturnsEmptyPtr d{};
|
|
assert(cuda::std::ranges::end(d) == &d.x);
|
|
assert(cuda::std::ranges::cend(d) == &d.x);
|
|
EndFunctionReturnsEmptyPtr dd{};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, decltype((dd))>, "");
|
|
assert(cuda::std::ranges::cend(dd) == &dd.x);
|
|
|
|
const EndFunctionWithDataMember e{};
|
|
assert(cuda::std::ranges::end(e) == &e.x);
|
|
assert(cuda::std::ranges::cend(e) == &e.x);
|
|
EndFunctionWithDataMember ee{};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, decltype((ee))>, "");
|
|
assert(cuda::std::ranges::cend(ee) == &ee.x);
|
|
|
|
const EndFunctionWithPrivateEndMember f{};
|
|
assert(cuda::std::ranges::end(f) == &f.y);
|
|
assert(cuda::std::ranges::cend(f) == &f.y);
|
|
EndFunctionWithPrivateEndMember ff{};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, decltype((ff))>, "");
|
|
assert(cuda::std::ranges::cend(ff) == &ff.y);
|
|
|
|
const BeginMemberEndFunction g{};
|
|
assert(cuda::std::ranges::end(g) == &g.x);
|
|
assert(cuda::std::ranges::cend(g) == &g.x);
|
|
BeginMemberEndFunction gg{};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, decltype((gg))>, "");
|
|
assert(cuda::std::ranges::cend(gg) == &gg.x);
|
|
|
|
return true;
|
|
}
|
|
static_assert(noexcept(cuda::std::ranges::end(cuda::std::declval<int (&)[10]>())));
|
|
static_assert(noexcept(cuda::std::ranges::cend(cuda::std::declval<int (&)[10]>())));
|
|
|
|
// needs c++17's guaranteed copy elision
|
|
#if !TEST_COMPILER(MSVC2019) // broken noexcept
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowMemberEnd
|
|
{
|
|
__host__ __device__ ThrowingIterator<int> begin() const;
|
|
__host__ __device__ ThrowingIterator<int> end() const noexcept; // auto(t.end()) doesn't throw
|
|
} ntme;
|
|
static_assert(noexcept(cuda::std::ranges::end(ntme)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cend(ntme)), "");
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowADLEnd
|
|
{
|
|
__host__ __device__ ThrowingIterator<int> begin() const;
|
|
__host__ __device__ friend ThrowingIterator<int> end(NoThrowADLEnd&) noexcept; // auto(end(t)) doesn't throw
|
|
__host__ __device__ friend ThrowingIterator<int> end(const NoThrowADLEnd&) noexcept;
|
|
} ntae;
|
|
static_assert(noexcept(cuda::std::ranges::end(ntae)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cend(ntae)), "");
|
|
#endif // !TEST_COMPILER(MSVC2019)
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowMemberEndReturnsRef
|
|
{
|
|
__host__ __device__ ThrowingIterator<int> begin() const;
|
|
__host__ __device__ ThrowingIterator<int>& end() const noexcept; // auto(t.end()) may throw
|
|
} ntmerr;
|
|
static_assert(!noexcept(cuda::std::ranges::end(ntmerr)), "");
|
|
static_assert(!noexcept(cuda::std::ranges::cend(ntmerr)), "");
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct EndReturnsArrayRef
|
|
{
|
|
__host__ __device__ auto begin() const noexcept -> int (&)[10];
|
|
__host__ __device__ auto end() const noexcept -> int (&)[10];
|
|
} erar;
|
|
static_assert(noexcept(cuda::std::ranges::end(erar)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cend(erar)), "");
|
|
|
|
#if TEST_STD_VER > 2017
|
|
// Test ADL-proofing.
|
|
struct Incomplete;
|
|
template <class T>
|
|
struct Holder
|
|
{
|
|
T t;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, Holder<Incomplete>*>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeEndT, Holder<Incomplete>*&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, Holder<Incomplete>*>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCEndT, Holder<Incomplete>*&>, "");
|
|
#endif // TEST_STD_VER > 2017
|
|
|
|
int main(int, char**)
|
|
{
|
|
static_assert(testReturnTypes(), "");
|
|
|
|
testArray();
|
|
static_assert(testArray(), "");
|
|
|
|
testEndMember();
|
|
static_assert(testEndMember(), "");
|
|
|
|
testEndFunction();
|
|
static_assert(testEndFunction(), "");
|
|
|
|
#if !TEST_COMPILER(MSVC2019) // broken noexcept
|
|
unused(ntme);
|
|
unused(ntae);
|
|
#endif // !TEST_COMPILER(MSVC2019)
|
|
unused(ntmerr);
|
|
unused(erar);
|
|
|
|
return 0;
|
|
}
|