Skip to content

Commit

Permalink
Implement comparison operators on SharedPreHashedString more robustly
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkewley committed Jul 22, 2024
1 parent 404704f commit 9ea6edc
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
26 changes: 24 additions & 2 deletions src/oscar/Utils/SharedPreHashedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,18 @@ namespace osc
return lhs.ptr_ == rhs.ptr_ or std::string_view{lhs} == std::string_view{rhs};
}

template<std::convertible_to<std::string_view> StringViewLike>
template<typename StringViewLike>
requires std::constructible_from<std::string_view, StringViewLike>
friend bool operator==(const SharedPreHashedString& lhs, const StringViewLike& rhs)
{
return std::string_view{lhs} == std::string_view{rhs};
return std::string_view{lhs} == rhs;
}

template<typename StringViewLike>
requires std::constructible_from<std::string_view, StringViewLike>
friend bool operator==(const StringViewLike& lhs, const SharedPreHashedString& rhs)
{
return lhs == std::string_view{rhs};
}

friend auto operator<=>(const SharedPreHashedString& lhs, const SharedPreHashedString& rhs)
Expand All @@ -231,6 +239,20 @@ namespace osc
return std::string_view{lhs} <=> std::string_view{rhs};
}

template<typename StringViewLike>
requires std::constructible_from<std::string_view, StringViewLike>
friend auto operator<=>(const SharedPreHashedString& lhs, const StringViewLike& rhs)
{
return std::string_view{lhs} <=> rhs;
}

template<typename StringViewLike>
requires std::constructible_from<std::string_view, StringViewLike>
friend auto operator<=>(const StringViewLike& lhs, const SharedPreHashedString& rhs)
{
return lhs <=> std::string_view{rhs};
}

// returns the number of different `SharedPreHashedString` instances (`this` included)
// managing the same underlying string data. In a multithreaded environment, the value
// returned by `use_count` is approximate (i.e. the implementation uses a
Expand Down
31 changes: 31 additions & 0 deletions tests/testoscar/Utils/TestSharedPreHashedString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

#include <gtest/gtest.h>

#include <algorithm>
#include <array>
#include <ranges>
#include <string_view>
#include <utility>

namespace rgs = std::ranges;
using namespace osc;
using namespace std::literals;

Expand Down Expand Up @@ -130,3 +134,30 @@ TEST(SharedPreHashedString, size_returns_expected_answers)
ASSERT_EQ(SharedPreHashedString{"ab"}.size(), 2);
ASSERT_EQ(SharedPreHashedString{"abc"}.size(), 3);
}

TEST(SharedPreHashedString, can_compare_with_cstring)
{
const char* cstr = "some string";
SharedPreHashedString str{cstr};

ASSERT_EQ(cstr, str);
ASSERT_EQ(str, cstr);
}

TEST(SharedPreHashedString, less_than_works_as_expected)
{
auto source_strings = std::to_array<std::string_view>({
"there once was a reference-counted string from Oscar...",
"... who wanted the same sorting behavior as the standard library =)",
"\nbut instead of writing proper permutation tests,",
" settled",
" For this",
" quite hacky",
" compromise",
});
std::vector<SharedPreHashedString> shared_strings(source_strings.begin(), source_strings.end());

rgs::sort(source_strings);
rgs::sort(shared_strings);
ASSERT_TRUE(rgs::equal(source_strings, shared_strings));
}

0 comments on commit 9ea6edc

Please sign in to comment.