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
456 lines
15 KiB
C++
456 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// std::ranges::begin
|
|
// std::ranges::cbegin
|
|
|
|
#include <cuda/std/cassert>
|
|
#include <cuda/std/ranges>
|
|
#include <cuda/std/utility>
|
|
|
|
#include "test_iterators.h"
|
|
#include "test_macros.h"
|
|
|
|
using RangeBeginT = decltype(cuda::std::ranges::begin);
|
|
using RangeCBeginT = decltype(cuda::std::ranges::cbegin);
|
|
|
|
TEST_GLOBAL_VARIABLE int globalBuff[8] = {};
|
|
|
|
// This has been made valid as a defect report for C++17 onwards, however both clang and gcc below 11.0 does not
|
|
// implement it
|
|
#if !TEST_COMPILER(GCC, <, 11)
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, int (&)[]>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, int (&)[]>, "");
|
|
#endif // !TEST_COMPILER(GCC, <, 11)
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, int (&)[10]>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, int (&)[10]>, "");
|
|
|
|
#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<RangeBeginT, int (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, int (&&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, int (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, int (&&)[10]>, "");
|
|
#endif // !TEST_COMPILER(MSVC, <, 19, 23)
|
|
|
|
struct Incomplete;
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Incomplete (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, const Incomplete (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Incomplete (&&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, const Incomplete (&&)[]>, "");
|
|
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Incomplete (&&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, const Incomplete (&&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Incomplete (&&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, const Incomplete (&&)[10]>, "");
|
|
|
|
// This case is IFNDR; we handle it SFINAE-friendly.
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Incomplete (&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, const Incomplete (&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Incomplete (&)[]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, const Incomplete (&)[]>, "");
|
|
|
|
// This case is IFNDR; we handle it SFINAE-friendly.
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Incomplete (&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, const Incomplete (&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Incomplete (&)[10]>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, const Incomplete (&)[10]>, "");
|
|
|
|
struct BeginMember
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr const int* begin() const
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
|
|
// Ensure that we can't call with rvalues with borrowing disabled.
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, BeginMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginMember&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, BeginMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginMember const&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, BeginMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, BeginMember&&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, BeginMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, BeginMember const&&>, "");
|
|
|
|
struct Different
|
|
{
|
|
__host__ __device__ char*& begin();
|
|
__host__ __device__ short*& begin() const;
|
|
};
|
|
__host__ __device__ constexpr bool testReturnTypes()
|
|
{
|
|
{
|
|
int* x[2] = {};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::begin(x)), int**>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cbegin(x)), int* const*>, "");
|
|
}
|
|
{
|
|
int x[2][2] = {};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::begin(x)), int(*)[2]>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cbegin(x)), const int(*)[2]>, "");
|
|
}
|
|
{
|
|
Different x{};
|
|
unused(x);
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::begin(x)), char*>, "");
|
|
static_assert(cuda::std::same_as<decltype(cuda::std::ranges::cbegin(x)), short*>, "");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
__host__ __device__ constexpr bool testArray()
|
|
{
|
|
int a[2] = {};
|
|
assert(cuda::std::ranges::begin(a) == a);
|
|
assert(cuda::std::ranges::cbegin(a) == a);
|
|
|
|
int b[2][2] = {};
|
|
assert(cuda::std::ranges::begin(b) == b);
|
|
assert(cuda::std::ranges::cbegin(b) == b);
|
|
|
|
BeginMember c[2] = {};
|
|
assert(cuda::std::ranges::begin(c) == c);
|
|
assert(cuda::std::ranges::cbegin(c) == c);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct BeginMemberReturnsInt
|
|
{
|
|
__host__ __device__ int begin() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginMemberReturnsInt const&>, "");
|
|
|
|
struct BeginMemberReturnsVoidPtr
|
|
{
|
|
__host__ __device__ const void* begin() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginMemberReturnsVoidPtr const&>, "");
|
|
|
|
struct EmptyBeginMember
|
|
{
|
|
struct iterator
|
|
{};
|
|
__host__ __device__ iterator begin() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, EmptyBeginMember const&>, "");
|
|
|
|
struct PtrConvertibleBeginMember
|
|
{
|
|
struct iterator
|
|
{
|
|
__host__ __device__ operator int*() const;
|
|
};
|
|
__host__ __device__ iterator begin() const;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, PtrConvertibleBeginMember const&>, "");
|
|
|
|
struct NonConstBeginMember
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr int* begin()
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, NonConstBeginMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, NonConstBeginMember const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, NonConstBeginMember&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, NonConstBeginMember const&>, "");
|
|
|
|
struct EnabledBorrowingBeginMember
|
|
{
|
|
__host__ __device__ constexpr const int* begin() const
|
|
{
|
|
return &globalBuff[0];
|
|
}
|
|
};
|
|
namespace cuda
|
|
{
|
|
namespace std
|
|
{
|
|
namespace ranges
|
|
{
|
|
template <>
|
|
_CCCL_INLINE_VAR constexpr bool enable_borrowed_range<EnabledBorrowingBeginMember> = true;
|
|
}
|
|
} // namespace std
|
|
} // namespace cuda
|
|
|
|
struct BeginMemberFunction
|
|
{
|
|
int x;
|
|
__host__ __device__ constexpr const int* begin() const
|
|
{
|
|
return &x;
|
|
}
|
|
__host__ __device__ friend int* begin(BeginMemberFunction const&);
|
|
};
|
|
|
|
struct EmptyPtrBeginMember
|
|
{
|
|
struct Empty
|
|
{};
|
|
Empty x;
|
|
__host__ __device__ constexpr const Empty* begin() const
|
|
{
|
|
return &x;
|
|
}
|
|
};
|
|
|
|
__host__ __device__ constexpr bool testBeginMember()
|
|
{
|
|
BeginMember a{};
|
|
assert(cuda::std::ranges::begin(a) == &a.x);
|
|
assert(cuda::std::ranges::cbegin(a) == &a.x);
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginMember&&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, BeginMember&&>, "");
|
|
|
|
NonConstBeginMember b{};
|
|
assert(cuda::std::ranges::begin(b) == &b.x);
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, NonConstBeginMember&>, "");
|
|
|
|
EnabledBorrowingBeginMember c{};
|
|
assert(cuda::std::ranges::begin(c) == &globalBuff[0]);
|
|
assert(cuda::std::ranges::cbegin(c) == &globalBuff[0]);
|
|
assert(cuda::std::ranges::begin(cuda::std::move(c)) == &globalBuff[0]);
|
|
assert(cuda::std::ranges::cbegin(cuda::std::move(c)) == &globalBuff[0]);
|
|
|
|
BeginMemberFunction d{};
|
|
assert(cuda::std::ranges::begin(d) == &d.x);
|
|
assert(cuda::std::ranges::cbegin(d) == &d.x);
|
|
|
|
EmptyPtrBeginMember e{};
|
|
assert(cuda::std::ranges::begin(e) == &e.x);
|
|
assert(cuda::std::ranges::cbegin(e) == &e.x);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct BeginFunction
|
|
{
|
|
int x;
|
|
__host__ __device__ friend constexpr const int* begin(BeginFunction const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
static_assert(cuda::std::is_invocable_v<RangeBeginT, BeginFunction const&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginFunction&&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginFunction&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, BeginFunction const&>, "");
|
|
static_assert(cuda::std::is_invocable_v<RangeCBeginT, BeginFunction&>, "");
|
|
|
|
struct BeginFunctionReturnsInt
|
|
{
|
|
__host__ __device__ friend int begin(BeginFunctionReturnsInt const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginFunctionReturnsInt const&>, "");
|
|
|
|
struct BeginFunctionReturnsVoidPtr
|
|
{
|
|
__host__ __device__ friend void* begin(BeginFunctionReturnsVoidPtr const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginFunctionReturnsVoidPtr const&>, "");
|
|
|
|
struct BeginFunctionReturnsPtrConvertible
|
|
{
|
|
struct iterator
|
|
{
|
|
__host__ __device__ operator int*() const;
|
|
};
|
|
__host__ __device__ friend iterator begin(BeginFunctionReturnsPtrConvertible const&);
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, BeginFunctionReturnsPtrConvertible const&>, "");
|
|
|
|
struct BeginFunctionByValue
|
|
{
|
|
__host__ __device__ friend constexpr const int* begin(BeginFunctionByValue)
|
|
{
|
|
return &globalBuff[1];
|
|
}
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, BeginFunctionByValue>, "");
|
|
|
|
struct BeginFunctionEnabledBorrowing
|
|
{
|
|
__host__ __device__ friend constexpr const int* begin(BeginFunctionEnabledBorrowing)
|
|
{
|
|
return &globalBuff[2];
|
|
}
|
|
};
|
|
|
|
namespace cuda
|
|
{
|
|
namespace std
|
|
{
|
|
namespace ranges
|
|
{
|
|
template <>
|
|
_CCCL_INLINE_VAR constexpr bool enable_borrowed_range<BeginFunctionEnabledBorrowing> = true;
|
|
}
|
|
} // namespace std
|
|
} // namespace cuda
|
|
|
|
struct BeginFunctionReturnsEmptyPtr
|
|
{
|
|
struct Empty
|
|
{};
|
|
Empty x;
|
|
__host__ __device__ friend constexpr const Empty* begin(BeginFunctionReturnsEmptyPtr const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
struct BeginFunctionWithDataMember
|
|
{
|
|
int x;
|
|
int begin;
|
|
__host__ __device__ friend constexpr const int* begin(BeginFunctionWithDataMember const& bf)
|
|
{
|
|
return &bf.x;
|
|
}
|
|
};
|
|
|
|
struct BeginFunctionWithPrivateBeginMember
|
|
{
|
|
int y;
|
|
__host__ __device__ friend constexpr const int* begin(BeginFunctionWithPrivateBeginMember const& bf)
|
|
{
|
|
return &bf.y;
|
|
}
|
|
|
|
private:
|
|
__host__ __device__ const int* begin() const;
|
|
};
|
|
|
|
__host__ __device__ constexpr bool testBeginFunction()
|
|
{
|
|
BeginFunction a{};
|
|
const BeginFunction aa{};
|
|
static_assert(!cuda::std::invocable<RangeBeginT, decltype((a))>, "");
|
|
assert(cuda::std::ranges::cbegin(a) == &a.x);
|
|
assert(cuda::std::ranges::begin(aa) == &aa.x);
|
|
assert(cuda::std::ranges::cbegin(aa) == &aa.x);
|
|
|
|
BeginFunctionByValue b{};
|
|
const BeginFunctionByValue bb{};
|
|
assert(cuda::std::ranges::begin(b) == &globalBuff[1]);
|
|
assert(cuda::std::ranges::cbegin(b) == &globalBuff[1]);
|
|
assert(cuda::std::ranges::begin(bb) == &globalBuff[1]);
|
|
assert(cuda::std::ranges::cbegin(bb) == &globalBuff[1]);
|
|
|
|
BeginFunctionEnabledBorrowing c{};
|
|
const BeginFunctionEnabledBorrowing cc{};
|
|
assert(cuda::std::ranges::begin(cuda::std::move(c)) == &globalBuff[2]);
|
|
assert(cuda::std::ranges::cbegin(cuda::std::move(c)) == &globalBuff[2]);
|
|
assert(cuda::std::ranges::begin(cuda::std::move(cc)) == &globalBuff[2]);
|
|
assert(cuda::std::ranges::cbegin(cuda::std::move(cc)) == &globalBuff[2]);
|
|
|
|
BeginFunctionReturnsEmptyPtr d{};
|
|
const BeginFunctionReturnsEmptyPtr dd{};
|
|
static_assert(!cuda::std::invocable<RangeBeginT, decltype((d))>, "");
|
|
assert(cuda::std::ranges::cbegin(d) == &d.x);
|
|
assert(cuda::std::ranges::begin(dd) == &dd.x);
|
|
assert(cuda::std::ranges::cbegin(dd) == &dd.x);
|
|
|
|
BeginFunctionWithDataMember e{};
|
|
const BeginFunctionWithDataMember ee{};
|
|
static_assert(!cuda::std::invocable<RangeBeginT, decltype((e))>, "");
|
|
assert(cuda::std::ranges::begin(ee) == &ee.x);
|
|
assert(cuda::std::ranges::cbegin(e) == &e.x);
|
|
assert(cuda::std::ranges::cbegin(ee) == &ee.x);
|
|
|
|
BeginFunctionWithPrivateBeginMember f{};
|
|
const BeginFunctionWithPrivateBeginMember ff{};
|
|
static_assert(!cuda::std::invocable<RangeBeginT, decltype((f))>, "");
|
|
assert(cuda::std::ranges::cbegin(f) == &f.y);
|
|
assert(cuda::std::ranges::begin(ff) == &ff.y);
|
|
assert(cuda::std::ranges::cbegin(ff) == &ff.y);
|
|
|
|
return true;
|
|
}
|
|
static_assert(noexcept(cuda::std::ranges::begin(cuda::std::declval<int (&)[10]>())));
|
|
static_assert(noexcept(cuda::std::ranges::cbegin(cuda::std::declval<int (&)[10]>())));
|
|
|
|
// needs c++17's guaranteed copy elision
|
|
#if !TEST_COMPILER(MSVC2019) // broken noexcept
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowMemberBegin
|
|
{
|
|
__host__ __device__ ThrowingIterator<int> begin() const noexcept; // auto(t.begin()) doesn't throw
|
|
} ntmb;
|
|
static_assert(noexcept(cuda::std::ranges::begin(ntmb)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cbegin(ntmb)), "");
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowADLBegin
|
|
{
|
|
__host__ __device__ friend ThrowingIterator<int> begin(NoThrowADLBegin&) noexcept; // auto(begin(t)) doesn't throw
|
|
__host__ __device__ friend ThrowingIterator<int> begin(const NoThrowADLBegin&) noexcept;
|
|
} ntab;
|
|
static_assert(noexcept(cuda::std::ranges::begin(ntab)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cbegin(ntab)), "");
|
|
#endif // !TEST_COMPILER(MSVC2019)
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct NoThrowMemberBeginReturnsRef
|
|
{
|
|
__host__ __device__ ThrowingIterator<int>& begin() const noexcept; // auto(t.begin()) may throw
|
|
} ntmbrr;
|
|
static_assert(!noexcept(cuda::std::ranges::begin(ntmbrr)), "");
|
|
static_assert(!noexcept(cuda::std::ranges::cbegin(ntmbrr)), "");
|
|
|
|
_CCCL_GLOBAL_CONSTANT struct BeginReturnsArrayRef
|
|
{
|
|
__host__ __device__ auto begin() const noexcept -> int (&)[10];
|
|
} brar;
|
|
static_assert(noexcept(cuda::std::ranges::begin(brar)), "");
|
|
static_assert(noexcept(cuda::std::ranges::cbegin(brar)), "");
|
|
|
|
#if TEST_STD_VER > 2017
|
|
// Test ADL-proofing.
|
|
struct Incomplete;
|
|
template <class T>
|
|
struct Holder
|
|
{
|
|
T t;
|
|
};
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Holder<Incomplete>*>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeBeginT, Holder<Incomplete>*&>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Holder<Incomplete>*>, "");
|
|
static_assert(!cuda::std::is_invocable_v<RangeCBeginT, Holder<Incomplete>*&>, "");
|
|
#endif // TEST_STD_VER > 2017
|
|
|
|
int main(int, char**)
|
|
{
|
|
static_assert(testReturnTypes(), "");
|
|
|
|
testArray();
|
|
static_assert(testArray(), "");
|
|
|
|
testBeginMember();
|
|
static_assert(testBeginMember(), "");
|
|
|
|
testBeginFunction();
|
|
static_assert(testBeginFunction(), "");
|
|
|
|
#if !TEST_COMPILER(MSVC2019) // broken noexcept
|
|
unused(ntmb);
|
|
unused(ntab);
|
|
#endif // !TEST_COMPILER(MSVC2019)
|
|
unused(ntmbrr);
|
|
unused(brar);
|
|
|
|
return 0;
|
|
}
|