Skip to content

Commit

Permalink
Merge pull request #702 from trcrsired/master
Browse files Browse the repository at this point in the history
Add string_view comparison
  • Loading branch information
trcrsired authored Apr 11, 2024
2 parents 799e656 + 5894293 commit d920bc1
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 22 deletions.
14 changes: 14 additions & 0 deletions include/fast_io_dsal/impl/common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
#pragma once

namespace fast_io
{

namespace containers
{

inline constexpr ::std::size_t npos{::std::numeric_limits<::std::size_t>::max()};

}

using ::fast_io::containers::npos;

} // namespace fast_io

namespace fast_io::containers::details
{
template <typename handle>
Expand Down
94 changes: 73 additions & 21 deletions include/fast_io_dsal/impl/string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,40 @@ class basic_string_view
using const_reference = value_type const &;
using pointer = value_type *;
using const_pointer = value_type const *;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = ::std::reverse_iterator<iterator>;
using iterator = const_iterator;
using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;

constexpr basic_string_view() noexcept = default;

constexpr basic_string_view(::std::nullptr_t) = delete;

constexpr basic_string_view(const_pointer p, size_type s) noexcept
explicit constexpr basic_string_view(const_pointer p, size_type s) noexcept
: ptr{p}, n{s}
{}

template <::std::size_t N>
explicit constexpr basic_string_view(char_type const (&buffer)[N]) noexcept
constexpr basic_string_view(char_type const (&buffer)[N]) noexcept
{
constexpr ::std::size_t nm1{N - 1u};
ptr = buffer;
n = nm1;
}

template <::std::contiguous_iterator Iter>
requires ::std::same_as<::std::remove_cvref_t<::std::iter_value_t<Iter>>, char_type>
constexpr basic_string_view(Iter const &first, Iter const &last) noexcept
: ptr{first}, n{last - first}
{
}

template <::std::ranges::contiguous_range rg>
requires(::std::same_as<::std::ranges::range_value_t<rg>, char_type> && !::std::is_array_v<::std::remove_cvref_t<rg>>)
explicit constexpr basic_string_view(::fast_io::freestanding::from_range_t, rg const &r) noexcept
: ptr{r.data()}, n{r.size()}
requires(::std::same_as<::std::ranges::range_value_t<rg>, char_type> && !::std::is_array_v<::std::remove_cvref_t<rg>> &&
!::std::is_rvalue_reference_v<rg>)
explicit constexpr basic_string_view(::fast_io::freestanding::from_range_t, rg const &&r) noexcept
: ptr{::std::ranges::cdata(r)}, n{::std::ranges::size(r)}
{
}

constexpr basic_string_view(::fast_io::basic_os_c_str<char_type> os_c_str) noexcept
: ptr(os_c_str.ptr), n(::fast_io::cstr_len(os_c_str.ptr))
constexpr basic_string_view(::fast_io::manipulators::basic_os_c_str<char_type> osstr) noexcept
: ptr(osstr.ptr), n(::fast_io::cstr_len(osstr.ptr))
{}
constexpr basic_string_view(::fast_io::manipulators::basic_os_c_str_with_known_size<char_type> osstr) noexcept
: ptr(osstr.ptr), n(osstr.n)
{}

constexpr basic_string_view(basic_string_view const &) noexcept = default;
Expand All @@ -60,12 +57,12 @@ class basic_string_view

inline constexpr bool is_empty() const noexcept
{
return n == 0;
return !n;
}

inline constexpr bool empty() const noexcept
{
return n == 0;
return !n;
}

inline constexpr size_type size() const noexcept
Expand Down Expand Up @@ -171,7 +168,7 @@ class basic_string_view
inline constexpr const_reference
back() const noexcept
{
if (n == 0) [[unlikely]]
if (!n) [[unlikely]]
{
::fast_io::fast_terminate();
}
Expand Down Expand Up @@ -199,7 +196,7 @@ class basic_string_view
inline constexpr const_reference
front() const noexcept
{
if (n == 0) [[unlikely]]
if (!n) [[unlikely]]
{
::fast_io::fast_terminate();
}
Expand All @@ -216,6 +213,32 @@ class basic_string_view
{
return *ptr;
}

inline constexpr bool starts_with(basic_string_view sv) const noexcept
{
if (sv.n <= n)
{
return ::std::equal(ptr, ptr + sv.n, sv.ptr, sv.ptr + sv.n);
}
return false;
}
inline constexpr bool starts_with_character(value_type ch) const noexcept
{
return !n && ch == *ptr;
}

inline constexpr bool ends_with(basic_string_view sv) const noexcept
{
if (sv.n <= n)
{
return ::std::equal(ptr + (n - sv.n), ptr + n, sv.ptr, sv.ptr + sv.n);
}
return false;
}
inline constexpr bool ends_with_character(value_type ch) const noexcept
{
return !n && ch == ptr[n - 1u];
}
};

template <::std::integral char_type>
Expand All @@ -236,12 +259,41 @@ constexpr bool operator==(basic_string_view<char_type> a, basic_string_view<char
return ::std::equal(a.ptr, a.ptr + a.n, b.ptr, b.ptr + b.n);
}

#if __cpp_lib_three_way_comparison >= 201907L
template <::std::integral char_type, ::std::size_t n>
constexpr bool operator==(basic_string_view<char_type> a, char_type const (&buffer)[n]) noexcept
{
constexpr ::std::size_t nm1{n - 1u};
return ::std::equal(a.ptr, a.ptr + a.n, buffer, buffer + nm1);
}

template <::std::integral char_type, ::std::size_t n>
constexpr bool operator==(char_type const (&buffer)[n], basic_string_view<char_type> a) noexcept
{
constexpr ::std::size_t nm1{n - 1u};
return ::std::equal(buffer, buffer + nm1, a.ptr, a.ptr + a.n);
}

#ifdef __cpp_lib_three_way_comparison
template <::std::integral char_type>
constexpr auto operator<=>(basic_string_view<char_type> a, basic_string_view<char_type> b) noexcept
{
return ::std::lexicographical_compare_three_way(a.ptr, a.ptr + a.n, b.ptr, b.ptr + b.n, ::std::compare_three_way{});
}

template <::std::integral char_type, ::std::size_t n>
constexpr auto operator<=>(basic_string_view<char_type> a, char_type const (&buffer)[n]) noexcept
{
constexpr ::std::size_t nm1{n - 1u};
return ::std::lexicographical_compare_three_way(a.ptr, a.ptr + a.n, buffer, buffer + nm1, ::std::compare_three_way{});
}

template <::std::integral char_type, ::std::size_t n>
constexpr auto operator<=>(char_type const (&buffer)[n], basic_string_view<char_type> a) noexcept
{
constexpr ::std::size_t nm1{n - 1u};
return ::std::lexicographical_compare_three_way(buffer, buffer + nm1, a.ptr, a.ptr + a.n, ::std::compare_three_way{});
}

#endif

} // namespace fast_io::containers
2 changes: 2 additions & 0 deletions tests/0026.container/0009.string_view/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_executable(string_view string_view.cc)
add_test(string_view string_view)
14 changes: 14 additions & 0 deletions tests/0026.container/0009.string_view/string_view.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <fast_io_dsal/string_view.h>
#include <fast_io.h>

int main()
{
::fast_io::string_view stvw("hello \0world\n");
::fast_io::io::println(stvw,
stvw == "hello world\n", "\n",
"hello world\n" == stvw, "\n",
stvw <=> "hello world\n", "\n",
"hello world\n" <=> stvw, "\n",
stvw.starts_with("hello"), "\n",
stvw.ends_with("\0world\n"));
}
3 changes: 2 additions & 1 deletion tests/0026.container/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ add_subdirectory(0003.deque)
add_subdirectory(0005.stack)
add_subdirectory(0006.queue)
add_subdirectory(0007.array)
add_subdirectory(0008.priority_queue)
add_subdirectory(0008.priority_queue)
add_subdirectory(0009.string_view)

0 comments on commit d920bc1

Please sign in to comment.