Skip to content
This repository has been archived by the owner on Mar 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #846 from KFilipek/task-basic_string_view_reimplem…
Browse files Browse the repository at this point in the history
…entation

Implementation of basic_string_view class
  • Loading branch information
Szymon Romik authored Sep 2, 2020
2 parents 3d9dcf5 + c9908f5 commit 34fab23
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 36 deletions.
96 changes: 65 additions & 31 deletions include/libpmemobj++/string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,80 @@ namespace obj
{

#if __cpp_lib_string_view

template <typename CharT, typename Traits = std::char_traits<CharT>>
using basic_string_view = std::basic_string_view<CharT, Traits>;
using string_view = std::string_view;
using wstring_view = std::basic_string_view<wchar_t>;
using u16string_view = std::basic_string_view<char16_t>;
using u32string_view = std::basic_string_view<char32_t>;

#else
/* XXX: implement it as a template (basic_string_view) */

/*! \class string_view
\brief Our brief std::string_view implementation.
If C++17's std::string_view implementation is not available, this one is
used to avoid unnecessary string copying.
*/
class string_view {
template <typename CharT, typename Traits = std::char_traits<CharT>>
class basic_string_view {
public:
string_view() noexcept;
string_view(const char *data, size_t size);
string_view(const std::string &s);
string_view(const char *data);
/* Member types */
using traits_type = Traits;
using value_type = CharT;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using reference = value_type &;
using const_reference = const value_type &;
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::string &s);
basic_string_view(const CharT *data);

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

const char *data() const noexcept;
std::size_t size() const noexcept;
const CharT *data() const noexcept;
size_type size() const noexcept;

const char &operator[](size_t p) const noexcept;
const CharT &operator[](size_type p) const noexcept;

int compare(const string_view &other) noexcept;
int compare(const basic_string_view &other) noexcept;

private:
const char *_data;
std::size_t _size;
const value_type *data_;
size_type size_;
};

using string_view = basic_string_view<char>;
using wstring_view = basic_string_view<wchar_t>;
using u16string_view = basic_string_view<char16_t>;
using u32string_view = basic_string_view<char32_t>;
/**
* Default constructor with empty data.
*/
inline string_view::string_view() noexcept : _data(""), _size(0)
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
: data_(nullptr), size_(0)
{
}

/**
* Constructor initialized by *data* and its *size*.
*
* @param[in] data pointer to the C-like string (char *) to initialize with,
* @param[in] data pointer to the C-like string to initialize with,
* it can contain null characters
* @param[in] size length of the given data
*/
inline string_view::string_view(const char *data, size_t size)
: _data(data), _size(size)
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data,
size_type size)
: data_(data), size_(size)
{
}

Expand All @@ -74,8 +100,9 @@ inline string_view::string_view(const char *data, size_t size)
*
* @param[in] s reference to the string to initialize with
*/
inline string_view::string_view(const std::string &s)
: _data(s.c_str()), _size(s.size())
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(const std::string &s)
: data_(s.c_str()), size_(s.size())
{
}

Expand All @@ -87,8 +114,9 @@ inline string_view::string_view(const std::string &s)
* it has to end with the terminating null
*character
*/
inline string_view::string_view(const char *data)
: _data(data), _size(std::char_traits<char>::length(data))
template <typename CharT, typename Traits>
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data)
: data_(data), size_(std::char_traits<char>::length(data))
{
}

Expand All @@ -98,29 +126,33 @@ inline string_view::string_view(const char *data)
*
* @return pointer to C-like string (char *), it may not end with null character
*/
inline const char *
string_view::data() const noexcept
template <typename CharT, typename Traits>
inline const CharT *
basic_string_view<CharT, Traits>::data() const noexcept
{
return _data;
return data_;
}

/**
* 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
*/
inline std::size_t
string_view::size() const noexcept
template <typename CharT, typename Traits>
inline typename basic_string_view<CharT, Traits>::size_type
basic_string_view<CharT, Traits>::size() const noexcept
{
return _size;
return size_;
}

/**
* Returns reference to a character at position @param[in] p
*
* @return reference to a char
*/
inline const char &string_view::operator[](size_t p) const noexcept
template <typename CharT, typename Traits>
inline const CharT &basic_string_view<CharT, Traits>::operator[](size_t p) const
noexcept
{
return data()[p];
}
Expand All @@ -133,10 +165,12 @@ inline const char &string_view::operator[](size_t p) const noexcept
* positive value if this is lexicographically greater than
*other, negative value if this is lexicographically less than other.
*/
template <typename CharT, typename Traits>
inline int
string_view::compare(const string_view &other) noexcept
basic_string_view<CharT, Traits>::compare(
const basic_string_view &other) noexcept
{
int ret = std::char_traits<char>::compare(
int ret = std::char_traits<CharT>::compare(
data(), other.data(), (std::min)(size(), other.size()));
if (ret != 0)
return ret;
Expand Down
48 changes: 43 additions & 5 deletions tests/string_view/string_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,64 @@

#include <iostream>
#include <libpmemobj++/string_view.hpp>
#include <string>

template <typename T>
void
test_string_view()
{
std::string s1("abc");
std::string s2("xyz");
std::string sLonger("01234567890123456789"
"01234567890123456789"
"01234567890123456789"
"01234567890123456789"
"01234567890123456789");
std::string sLonger2("xyz34567890123456789"
"01234567890123456789"
"01234567890123456789"
"01234567890123456789"
"01234567890123456789");

pmem::obj::string_view v1(s1);
pmem::obj::string_view v2(s2);
std::basic_string<T> ts1(s1.begin(), s1.end());
std::basic_string<T> ts2(s2.begin(), s2.end());
std::basic_string<T> tsLonger(sLonger.begin(), sLonger.end());
std::basic_string<T> tsLonger2(sLonger2.begin(), sLonger2.end());

UT_ASSERT(s1.data() == v1.data());
UT_ASSERT(s1.size() == v1.size());
pmem::obj::basic_string_view<T> vEmpty;
pmem::obj::basic_string_view<T> v1(ts1.data(), ts1.length());
pmem::obj::basic_string_view<T> v2(ts2.data(), ts2.length());
pmem::obj::basic_string_view<T> vLonger(tsLonger.data(),
tsLonger.length());
pmem::obj::basic_string_view<T> vLonger2(tsLonger2.data(),
tsLonger2.length());

UT_ASSERT(ts1.data() == v1.data());
UT_ASSERT(ts1.size() == v1.size());

UT_ASSERT(v1.compare(v2) < 0);
UT_ASSERT(v2.compare(v1) > 0);
UT_ASSERT(v1.compare(v1) == 0);

UT_ASSERT(v1.compare(vLonger) != 0);

UT_ASSERT(v2.compare(vLonger2) < 0);
UT_ASSERT(vLonger2.compare(v2) > 0);

UT_ASSERT(vEmpty.data() == nullptr);
UT_ASSERT(vEmpty.size() == 0);
}

void
run_test()
{
test_string_view<char>();
test_string_view<wchar_t>();
test_string_view<uint8_t>();
}

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

0 comments on commit 34fab23

Please sign in to comment.