Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 83 additions & 23 deletions include/libpmemobj++/string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <algorithm>
#include <cassert>
#include <stdexcept>
#include <string>

#if __cpp_lib_string_view
Expand Down Expand Up @@ -53,19 +54,24 @@ class basic_string_view {
using pointer = value_type *;
using const_pointer = const value_type *;

basic_string_view() noexcept;
basic_string_view(const CharT *data, size_type size);
basic_string_view(const std::basic_string<CharT, Traits> &s);
basic_string_view(const CharT *data);
constexpr basic_string_view() noexcept;
constexpr basic_string_view(const CharT *data, size_type size);
constexpr basic_string_view(const std::basic_string<CharT, Traits> &s);
constexpr basic_string_view(const CharT *data);

basic_string_view(const basic_string_view &rhs) noexcept = default;
constexpr basic_string_view(const basic_string_view &rhs) noexcept =
default;
basic_string_view &
operator=(const basic_string_view &rhs) noexcept = default;

const CharT *data() const noexcept;
size_type size() const noexcept;
constexpr const CharT *data() const noexcept;
constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;

const CharT &operator[](size_type p) const noexcept;
const CharT &at(size_type pos) const;
constexpr const CharT &operator[](size_type pos) const noexcept;
constexpr const_reference front() const noexcept;
constexpr const_reference back() const noexcept;

int compare(const basic_string_view &other) const noexcept;

Expand All @@ -83,7 +89,7 @@ using u32string_view = basic_string_view<char32_t>;
* Default constructor with empty data.
*/
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
constexpr inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
: data_(nullptr), size_(0)
{
}
Expand All @@ -96,8 +102,8 @@ inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
* @param[in] size length of the given data.
*/
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data,
size_type size)
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
const CharT *data, size_type size)
: data_(data), size_(size)
{
}
Expand All @@ -108,7 +114,7 @@ inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data,
* @param[in] s reference to the string to initialize with.
*/
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
const std::basic_string<CharT, Traits> &s)
: data_(s.c_str()), size_(s.size())
{
Expand All @@ -122,7 +128,8 @@ inline basic_string_view<CharT, Traits>::basic_string_view(
* it has to end with the terminating null character.
*/
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data)
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
const CharT *data)
: data_(data), size_(Traits::length(data))
{
}
Expand All @@ -135,7 +142,7 @@ inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data)
* character.
*/
template <typename CharT, typename Traits>
inline const CharT *
constexpr inline const CharT *
basic_string_view<CharT, Traits>::data() const noexcept
{
return data_;
Expand All @@ -144,27 +151,80 @@ basic_string_view<CharT, Traits>::data() const noexcept
/**
* Returns count of characters stored in this pmem::obj::string_view data.
*
* @return pointer to C-like string (char *), it may not end with null
* character.
* @return the number of CharT elements in the view.
*/
template <typename CharT, typename Traits>
inline typename basic_string_view<CharT, Traits>::size_type
constexpr inline typename basic_string_view<CharT, Traits>::size_type
basic_string_view<CharT, Traits>::size() const noexcept
{
return size_;
}

/**
* Returns reference to a character at position @param[in] p .
* Returns count of characters stored in this pmem::obj::string_view data.
*
* @return reference to a char.
* @return the number of CharT elements in the view.
*/
template <typename CharT, typename Traits>
inline const CharT &basic_string_view<CharT, Traits>::operator[](size_t p) const
noexcept
constexpr inline typename basic_string_view<CharT, Traits>::size_type
basic_string_view<CharT, Traits>::length() const noexcept
{
return size_;
}

/**
* Returns reference to a character at position @param[in] pos .
*
* @return reference to the char.
*/
template <typename CharT, typename Traits>
constexpr inline const CharT &
basic_string_view<CharT, Traits>::operator[](size_t pos) const noexcept
{
return data()[pos];
}

/**
* Returns reference to the character at position @param[in] pos and
* performs bound checking.
*
* @return reference to the char.
*
* @throw std::out_of_range when out of bounds occurs.
*/
template <typename CharT, typename Traits>
inline const CharT &
basic_string_view<CharT, Traits>::at(size_t pos) const
{
if (pos >= size())
throw std::out_of_range("Accessing a position out of bounds!");
return data()[pos];
}

/**
* Returns reference to the last character in the view.
* The behavior is undefined if empty() == true.
*
* @return reference to the last character.
*/
template <typename CharT, typename Traits>
constexpr inline const CharT &
basic_string_view<CharT, Traits>::back() const noexcept
{
return operator[](size() - 1);
}

/**
* Returns reference to the first character in the view.
* The behavior is undefined if empty() == true.
*
* @return reference to the first character.
*/
template <typename CharT, typename Traits>
constexpr inline const CharT &
basic_string_view<CharT, Traits>::front() const noexcept
{
assert(p < size());
return data()[p];
return operator[](0);
}

/**
Expand Down
15 changes: 15 additions & 0 deletions tests/external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,21 @@ if (TEST_STRING)
# XXX: port libcxx test basic_string/string.cons/initializer_list_assignment.pass
add_test_expect_failure(string_libcxx_string_view libcxx/basic_string/string.cons/string_view.fail.cpp)

build_test(string_libcxx_string_view_at libcxx/string.view/string.view.access/at.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_at TRACERS none pmemcheck memcheck)

build_test(string_libcxx_string_view_back libcxx/string.view/string.view.access/back.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_back TRACERS none pmemcheck memcheck)

build_test(string_libcxx_string_view_data libcxx/string.view/string.view.access/data.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_data TRACERS none pmemcheck memcheck)

build_test(string_libcxx_string_view_front libcxx/string.view/string.view.access/front.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_front TRACERS none pmemcheck memcheck)

build_test(string_libcxx_string_view_index libcxx/string.view/string.view.access/index.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_index TRACERS none pmemcheck memcheck)

if(MSVC_VERSION GREATER_EQUAL 1920)
build_test(string_libcxx_string_view_opeq_string_view libcxx/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp)
add_test_generic(NAME string_libcxx_string_view_opeq_string_view TRACERS none pmemcheck memcheck)
Expand Down
65 changes: 65 additions & 0 deletions tests/external/libcxx/string.view/string.view.access/at.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Copyright 2020, Intel Corporation
//
// Modified to test pmem::obj containers
//

// NOTE: Older versions of clang have a bug where they fail to evaluate
// string_view::at as a constant expression.
// XFAIL: clang-3.4, clang-3.3

// <string_view>

// constexpr const _CharT& at(size_type _pos) const;

#include "unittest.hpp"

#include <libpmemobj++/string_view.hpp>

template <typename CharT>
void
test(const CharT *s, size_t len)
{
pmem::obj::basic_string_view<CharT> sv(s, len);
UT_ASSERT(sv.length() == len);
for (size_t i = 0; i < len; ++i) {
UT_ASSERT(sv.at(i) == s[i]);
UT_ASSERT(&sv.at(i) == s + i);
}

try {
(void)sv.at(len);
} catch (const std::out_of_range &) {
return;
}
UT_ASSERT(false);
}

static void
run()
{
test("ABCDE", 5);
test("a", 1);

test(L"ABCDE", 5);
test(L"a", 1);

test(u"ABCDE", 5);
test(u"a", 1);

test(U"ABCDE", 5);
test(U"a", 1);
}

int
main(int argc, char *argv[])
{
return run_test([&] { run(); });
}
64 changes: 64 additions & 0 deletions tests/external/libcxx/string.view/string.view.access/back.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Copyright 2020, Intel Corporation
//
// Modified to test pmem::obj containers
//

// <string_view>

// constexpr const _CharT& front();

#include "unittest.hpp"

#include <libpmemobj++/string_view.hpp>

template <typename CharT>
bool
test(const CharT *s, size_t len)
{
typedef pmem::obj::basic_string_view<CharT> SV;
SV sv(s, len);

static_assert(std::is_same<decltype(sv.back()),
typename SV::const_reference>::value,
"must be const_reference");
static_assert(noexcept(sv.back()), "Operation must be noexcept");
UT_ASSERT(sv.length() == len);
UT_ASSERT(sv.back() == s[len - 1]);
return &sv.back() == s + len - 1;
}

static void
run()
{
UT_ASSERT(test("ABCDE", 5));
UT_ASSERT(test("a", 1));

UT_ASSERT(test(L"ABCDE", 5));
UT_ASSERT(test(L"a", 1));

UT_ASSERT(test(u"ABCDE", 5));
UT_ASSERT(test(u"a", 1));

UT_ASSERT(test(U"ABCDE", 5));
UT_ASSERT(test(U"a", 1));

{
constexpr pmem::obj::basic_string_view<char> sv("ABC", 2);
static_assert(sv.length() == 2, "");
static_assert(sv.back() == 'B', "");
}
}

int
main(int argc, char *argv[])
{
return run_test([&] { run(); });
}
58 changes: 58 additions & 0 deletions tests/external/libcxx/string.view/string.view.access/data.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Copyright 2020, Intel Corporation
//
// Modified to test pmem::obj containers
//

// <string_view>

// constexpr const _CharT* data() const noexcept;

#include "unittest.hpp"

#include <libpmemobj++/string_view.hpp>

template <typename CharT>
void
test(const CharT *s, size_t len)
{
pmem::obj::basic_string_view<CharT> sv(s, len);
UT_ASSERT(sv.length() == len);
UT_ASSERT(sv.data() == s);
}

static void
run()
{
test("ABCDE", 5);
test("a", 1);

test(L"ABCDE", 5);
test(L"a", 1);

test(u"ABCDE", 5);
test(u"a", 1);

test(U"ABCDE", 5);
test(U"a", 1);

{
constexpr const char *s = "ABC";
constexpr pmem::obj::basic_string_view<char> sv(s, 2);
static_assert(sv.length() == 2, "");
static_assert(sv.data() == s, "");
}
}

int
main(int argc, char *argv[])
{
return run_test([&] { run(); });
}
Loading