Skip to content

Commit

Permalink
Implement views::empty
Browse files Browse the repository at this point in the history
This implements `std::ranges::views::empty`, see https://en.cppreference.com/w/cpp/ranges/empty_view
  • Loading branch information
miscco committed Jan 7, 2025
1 parent f9c0207 commit 74ff83d
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 1 deletion.
80 changes: 80 additions & 0 deletions libcudacxx/include/cuda/std/__ranges/empty_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// -*- 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) 2025 NVIDIA CORPORATION & AFFILIATES
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCUDACXX___RANGES_EMPTY_VIEW_H
#define _LIBCUDACXX___RANGES_EMPTY_VIEW_H

#include <cuda/std/detail/__config>

#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
# pragma GCC system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
# pragma clang system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
# pragma system_header
#endif // no system header

#include <cuda/std/__ranges/enable_borrowed_range.h>
#include <cuda/std/__ranges/view_interface.h>
#include <cuda/std/__type_traits/is_object.h>

#if _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER(MSVC2017)

_LIBCUDACXX_BEGIN_NAMESPACE_RANGES
_LIBCUDACXX_BEGIN_NAMESPACE_RANGES_ABI

_CCCL_TEMPLATE(class _Tp)
_CCCL_REQUIRES(_CCCL_TRAIT(is_object, _Tp))
class empty_view : public view_interface<empty_view<_Tp>>
{
public:
_LIBCUDACXX_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept
{
return nullptr;
}
_LIBCUDACXX_HIDE_FROM_ABI static constexpr _Tp* end() noexcept
{
return nullptr;
}
_LIBCUDACXX_HIDE_FROM_ABI static constexpr _Tp* data() noexcept
{
return nullptr;
}
_LIBCUDACXX_HIDE_FROM_ABI static constexpr size_t size() noexcept
{
return 0;
}
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool empty() noexcept
{
return true;
}
};

_LIBCUDACXX_END_NAMESPACE_RANGES_ABI

template <class _Tp>
_CCCL_INLINE_VAR constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;

_LIBCUDACXX_END_NAMESPACE_RANGES

_LIBCUDACXX_BEGIN_NAMESPACE_VIEWS

# if _CCCL_COMPILER(MSVC)
template <class _Tp>
_CCCL_INLINE_VAR constexpr empty_view<_Tp> empty{};
# else // ^^^ _CCCL_COMPILER_MSVC ^^^ / vvv !_CCCL_COMPILER_MSVC vvv
template <class _Tp>
_CCCL_GLOBAL_CONSTANT empty_view<_Tp> empty{};
# endif // !_CCCL_COMPILER_MSVC

_LIBCUDACXX_END_NAMESPACE_VIEWS

#endif // _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER_MSVC_2017

#endif // _LIBCUDACXX___RANGES_EMPTY_VIEW_H
1 change: 1 addition & 0 deletions libcudacxx/include/cuda/std/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ _CCCL_DIAG_SUPPRESS_MSVC(4848)
#include <cuda/std/__ranges/dangling.h>
#include <cuda/std/__ranges/data.h>
#include <cuda/std/__ranges/empty.h>
#include <cuda/std/__ranges/empty_view.h>
#include <cuda/std/__ranges/enable_borrowed_range.h>
#include <cuda/std/__ranges/enable_view.h>
#include <cuda/std/__ranges/rbegin.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: msvc-19.16

// template<class T>
// inline constexpr bool enable_borrowed_range<empty_view<T>> = true;

#include <cuda/std/ranges>

#include "test_range.h"

static_assert(cuda::std::ranges::borrowed_range<cuda::std::ranges::empty_view<int>>);
static_assert(cuda::std::ranges::borrowed_range<cuda::std::ranges::empty_view<int*>>);
static_assert(cuda::std::ranges::borrowed_range<cuda::std::ranges::empty_view<BorrowedView>>);
#if _LIBCUDACXX_HAS_RANGES
static_assert(cuda::std::ranges::borrowed_range<cuda::std::ranges::empty_view<NonBorrowedView>>);
#endif

int main(int, char**)
{
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//===----------------------------------------------------------------------===//
//
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: msvc-19.16

// template<class T>
// class empty_view;

#include <cuda/std/cassert>
#include <cuda/std/ranges>

#include "test_macros.h"

template <class T>
__host__ __device__ constexpr void testType()
{
static_assert(cuda::std::ranges::range<cuda::std::ranges::empty_view<T>>);
static_assert(cuda::std::ranges::range<const cuda::std::ranges::empty_view<T>>);
static_assert(cuda::std::ranges::view<cuda::std::ranges::empty_view<T>>);

cuda::std::ranges::empty_view<T> empty{};

assert(empty.begin() == nullptr);
assert(empty.end() == nullptr);
assert(empty.data() == nullptr);
assert(empty.size() == 0);
assert(empty.empty() == true);

assert(cuda::std::ranges::begin(empty) == nullptr);
assert(cuda::std::ranges::end(empty) == nullptr);
assert(cuda::std::ranges::data(empty) == nullptr);
assert(cuda::std::ranges::size(empty) == 0);
assert(cuda::std::ranges::empty(empty) == true);
}

struct Empty
{};
struct BigType
{
char buff[8];
};

#if TEST_STD_VER >= 2020
template <class T>
concept ValidEmptyView = requires { typename cuda::std::ranges::empty_view<T>; };
#else // ^^^ C++20 ^^^ / vvv C++17 vvv
template <class T, class = void>
constexpr bool ValidEmptyView = false;

template <class T>
constexpr bool ValidEmptyView<T, cuda::std::void_t<cuda::std::ranges::empty_view<T>>> = true;
#endif // TEST_STD_VER <= 2017

__host__ __device__ constexpr bool test()
{
// Not objects:
static_assert(!ValidEmptyView<int&>);
static_assert(!ValidEmptyView<void>);

testType<int>();
testType<const int>();
testType<int*>();
testType<Empty>();
testType<const Empty>();
testType<BigType>();

return true;
}

int main(int, char**)
{
test();
static_assert(test());

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// 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) 2025 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: msvc-19.16

// template <class _Tp>
// inline constexpr empty_view<_Tp> empty{};

#include <cuda/std/cassert>
#include <cuda/std/ranges>

#include "test_macros.h"

template <class T>
__host__ __device__ constexpr void testType()
{
ASSERT_SAME_TYPE(decltype(cuda::std::views::empty<T>), const cuda::std::ranges::empty_view<T>);
ASSERT_SAME_TYPE(decltype((cuda::std::views::empty<T>) ), const cuda::std::ranges::empty_view<T>&);

auto v = cuda::std::views::empty<T>;
assert(cuda::std::ranges::empty(v));
}

struct Empty
{};
struct BigType
{
char buff[8];
};

__host__ __device__ constexpr bool test()
{
testType<int>();
testType<const int>();
testType<int*>();
testType<Empty>();
testType<const Empty>();
testType<BigType>();

return true;
}

int main(int, char**)
{
test();
static_assert(test());

return 0;
}
4 changes: 3 additions & 1 deletion libcudacxx/test/support/test_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ _CCCL_INLINE_VAR constexpr bool enable_borrowed_range<BorrowedRange> = true;
static_assert(!cuda::std::ranges::view<BorrowedRange>, "");
static_assert(cuda::std::ranges::borrowed_range<BorrowedRange>, "");

#if _LIBCUDACXX_HAS_RANGES
#if _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER(MSVC2017)
using BorrowedView = cuda::std::ranges::empty_view<int>;
static_assert(cuda::std::ranges::view<BorrowedView>, "");
static_assert(cuda::std::ranges::borrowed_range<BorrowedView>, "");
#endif // _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER(MSVC2017)

#if _LIBCUDACXX_HAS_RANGES
using NonBorrowedView = cuda::std::ranges::single_view<int>;
static_assert(cuda::std::ranges::view<NonBorrowedView>, "");
static_assert(!cuda::std::ranges::borrowed_range<NonBorrowedView>, "");
Expand Down

0 comments on commit 74ff83d

Please sign in to comment.