Skip to content

Commit 70e41a2

Browse files
authored
[orc-rt] Add orc_rt::span, a pre-c++20 std::span substitute (llvm#154478)
This patch introduces an orc_rt::span class template that the ORC runtime can use until we're able to move to c++20.
1 parent a9de444 commit 70e41a2

File tree

5 files changed

+114
-7
lines changed

5 files changed

+114
-7
lines changed

orc-rt/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
set(ORC_RT_HEADERS
22
orc-rt-c/orc-rt.h
3+
orc-rt/span.h
34
)
45

56
# TODO: Switch to filesets when we move to cmake-3.23.

orc-rt/include/orc-rt/span.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===---------- span.h - Substitute for C++20 std::span ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// TODO: Replace all uses with std::span once we can use C++20.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef ORC_RT_SPAN_H
14+
#define ORC_RT_SPAN_H
15+
16+
#include <cstddef>
17+
#include <limits>
18+
19+
namespace orc_rt {
20+
21+
constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
22+
23+
/// A substitute for std::span (and llvm::ArrayRef).
24+
/// FIXME: Remove in favor of std::span once we can use c++20.
25+
template <typename T, std::size_t Extent = dynamic_extent> class span {
26+
public:
27+
typedef T element_type;
28+
typedef std::remove_cv<T> value_type;
29+
typedef std::size_t size_type;
30+
typedef std::ptrdiff_t difference_type;
31+
typedef T *pointer;
32+
typedef const T *const_pointer;
33+
typedef T &reference;
34+
typedef const T &const_reference;
35+
36+
typedef pointer iterator;
37+
38+
static constexpr std::size_t extent = Extent;
39+
40+
constexpr span() noexcept = default;
41+
constexpr span(T *first, size_type count) noexcept
42+
: Data(first), Size(count) {}
43+
44+
template <std::size_t N>
45+
constexpr span(T (&arr)[N]) noexcept : Data(&arr[0]), Size(N) {}
46+
47+
constexpr iterator begin() const noexcept { return Data; }
48+
constexpr iterator end() const noexcept { return Data + Size; }
49+
constexpr pointer data() const noexcept { return Data; }
50+
constexpr reference operator[](size_type idx) const { return Data[idx]; }
51+
constexpr size_type size() const noexcept { return Size; }
52+
constexpr bool empty() const noexcept { return Size == 0; }
53+
54+
private:
55+
T *Data = nullptr;
56+
size_type Size = 0;
57+
};
58+
59+
} // namespace orc_rt
60+
61+
#endif // ORC_RT_SPAN_H

orc-rt/unittests/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function(add_orc_rt_unittest test_dirname)
1212
endfunction()
1313

1414
add_orc_rt_unittest(CoreTests
15-
init.cpp
15+
span-test.cpp
1616
DISABLE_LLVM_LINK_LLVM_DYLIB
1717
)
18+
target_link_libraries(CoreTests PRIVATE orc-rt-executor)

orc-rt/unittests/init.cpp

Lines changed: 0 additions & 6 deletions
This file was deleted.

orc-rt/unittests/span-test.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===- span_test.cpp ------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Tests orc-rt's span implementation.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "orc-rt/span.h"
14+
#include "gtest/gtest.h"
15+
16+
#include <sstream>
17+
#include <string>
18+
19+
using namespace orc_rt;
20+
21+
TEST(SpanTest, SpanDefaultConstruction) {
22+
span<int> S;
23+
EXPECT_TRUE(S.empty()) << "Default constructed span not empty";
24+
EXPECT_EQ(S.size(), 0U) << "Default constructed span size not zero";
25+
EXPECT_EQ(S.begin(), S.end()) << "Default constructed span begin != end";
26+
}
27+
28+
TEST(SpanTest, SpanConstructFromFixedArray) {
29+
int A[] = {1, 2, 3, 4, 5};
30+
span<int> S(A);
31+
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
32+
EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
33+
EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
34+
<< "Unexpected iterator range size";
35+
EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
36+
for (unsigned I = 0; I != S.size(); ++I)
37+
EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
38+
}
39+
40+
TEST(SpanTest, SpanConstructFromIteratorAndSize) {
41+
int A[] = {1, 2, 3, 4, 5};
42+
span<int> S(&A[0], 5);
43+
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
44+
EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
45+
EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
46+
<< "Unexpected iterator range size";
47+
EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
48+
for (unsigned I = 0; I != S.size(); ++I)
49+
EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
50+
}

0 commit comments

Comments
 (0)