[ORC-RT] Add string_view and span utilities for use by the ORC runtime.

These are substitutes for std::string_view (and llvm::StringRef) and std::span
(and llvm::ArrayRef) for use by the ORC runtime.
This commit is contained in:
Lang Hames 2021-05-20 08:56:03 -07:00
parent a26288e803
commit d22b27cfde
3 changed files with 179 additions and 0 deletions

98
compiler-rt/lib/orc/adt.h Normal file
View File

@ -0,0 +1,98 @@
//===----------------------- adt.h - Handy ADTs -----------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file is a part of the ORC runtime support library.
//
//===----------------------------------------------------------------------===//
#ifndef ORC_RT_ADT_H
#define ORC_RT_ADT_H
#include <cstring>
#include <limits>
#include <string>
namespace __orc_rt {
constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
/// A substitute for std::span (and llvm::ArrayRef).
/// FIXME: Remove in favor of std::span once we can use c++20.
template <typename T, std::size_t Extent = dynamic_extent> class span {
public:
typedef T element_type;
typedef std::remove_cv<T> value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T &reference;
typedef const T &const_reference;
typedef pointer iterator;
static constexpr std::size_t extent = Extent;
constexpr span() noexcept = default;
constexpr span(T *first, size_type count) noexcept
: Data(first), Size(count) {}
template <std::size_t N>
constexpr span(T (&arr)[N]) noexcept : Data(&arr[0]), Size(N) {}
constexpr iterator begin() const noexcept { return Data; }
constexpr iterator end() const noexcept { return Data + Size; }
constexpr pointer data() const noexcept { return Data; }
constexpr reference operator[](size_type idx) const { return Data[idx]; }
constexpr size_type size() const noexcept { return Size; }
constexpr bool empty() const noexcept { return Size == 0; }
private:
T *Data = nullptr;
size_type Size = 0;
};
/// A substitue for std::string_view (and llvm::StringRef).
/// FIXME: Remove in favor of std::string_view once we have c++17.
class string_view {
public:
typedef char value_type;
typedef char *pointer;
typedef const char *const_pointer;
typedef char &reference;
typedef const char &const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef const_pointer const_iterator;
typedef const_iterator iterator;
constexpr string_view() noexcept = default;
constexpr string_view(const char *S, size_type Count)
: Data(S), Size(Count) {}
string_view(const char *S) : Data(S), Size(strlen(S)) {}
constexpr const_iterator begin() const noexcept { return Data; }
constexpr const_iterator end() const noexcept { return Data + Size; }
constexpr const_pointer data() const noexcept { return Data; }
constexpr const_reference operator[](size_type idx) { return Data[idx]; }
constexpr size_type size() const noexcept { return Size; }
constexpr bool empty() const noexcept { return Size == 0; }
private:
const char *Data = nullptr;
size_type Size = 0;
};
inline std::string to_string(string_view SV) {
return std::string(SV.data(), SV.size());
}
} // end namespace __orc_rt
#endif // ORC_RT_COMMON_H

View File

@ -80,6 +80,7 @@ macro(add_orc_unittest testname)
endmacro()
set(UNITTEST_SOURCES
adt_test.cpp
error_test.cpp
extensible_rtti_test.cpp
orc_unit_test_main.cpp

View File

@ -0,0 +1,80 @@
//===-- adt_test.cpp ------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file is a part of the ORC runtime.
//
//===----------------------------------------------------------------------===//
#include "adt.h"
#include "gtest/gtest.h"
using namespace __orc_rt;
TEST(ADTTest, SpanDefaultConstruction) {
span<int> S;
EXPECT_TRUE(S.empty()) << "Default constructed span not empty";
EXPECT_EQ(S.size(), 0U) << "Default constructed span size not zero";
EXPECT_EQ(S.begin(), S.end()) << "Default constructed span begin != end";
}
TEST(ADTTest, SpanConstructFromFixedArray) {
int A[] = {1, 2, 3, 4, 5};
span<int> S(A);
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
<< "Unexpected iterator range size";
EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
for (unsigned I = 0; I != S.size(); ++I)
EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
}
TEST(ADTTest, SpanConstructFromIteratorAndSize) {
int A[] = {1, 2, 3, 4, 5};
span<int> S(&A[0], 5);
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
<< "Unexpected iterator range size";
EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
for (unsigned I = 0; I != S.size(); ++I)
EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
}
TEST(ADTTest, StringViewDefaultConstruction) {
string_view S;
EXPECT_TRUE(S.empty()) << "Default constructed span not empty";
EXPECT_EQ(S.size(), 0U) << "Default constructed span size not zero";
EXPECT_EQ(S.begin(), S.end()) << "Default constructed span begin != end";
}
TEST(ADTTest, StringViewConstructFromCharPtrAndSize) {
const char *Str = "abcdefg";
string_view S(Str, 5);
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
<< "Unexpected iterator range size";
EXPECT_EQ(S.data(), &Str[0]) << "Span data has unexpected value";
for (unsigned I = 0; I != S.size(); ++I)
EXPECT_EQ(S[I], Str[I]) << "Unexpected span element value";
}
TEST(ADTTest, StringViewConstructFromCharPtr) {
const char *Str = "abcdefg";
size_t StrLen = strlen(Str);
string_view S(Str);
EXPECT_FALSE(S.empty()) << "Span should be non-empty";
EXPECT_EQ(S.size(), StrLen) << "Span has unexpected size";
EXPECT_EQ(std::distance(S.begin(), S.end()), StrLen)
<< "Unexpected iterator range size";
EXPECT_EQ(S.data(), &Str[0]) << "Span data has unexpected value";
for (unsigned I = 0; I != S.size(); ++I)
EXPECT_EQ(S[I], Str[I]) << "Unexpected span element value";
}