Skip to content

Commit

Permalink
Mv sortedSizeArrayElement definition to word.h, and test in word_test
Browse files Browse the repository at this point in the history
  • Loading branch information
jackhwalters committed Jul 28, 2024
1 parent 5fbde12 commit eacbf70
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 39 deletions.
37 changes: 37 additions & 0 deletions include/faker-cxx/word.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <string_view>
#include "faker-cxx/export.h"

#include "faker-cxx/helper.h"

namespace faker::word
{
/**
Expand Down Expand Up @@ -140,4 +142,39 @@ FAKER_CXX_EXPORT std::string_view preposition(std::optional<unsigned> length = s
* @endcode
*/
FAKER_CXX_EXPORT std::string_view verb(std::optional<unsigned> length = std::nullopt);

template <typename It>
auto sortedSizeArrayElement(std::optional<unsigned int> length, It start, It end) -> decltype(*std::declval<It>())
{
if (!length)
{
return helper::arrayElement(start, end);
}

size_t length_64 = *length;
auto lower_it = ::std::lower_bound(start, end, length_64,
[](const auto& lhs, const auto& value) { return lhs.size() < value; });

if (lower_it == end)
{
return helper::arrayElement(start, end);
}

if (lower_it->size() != length)
{
return helper::arrayElement(start, end);
}

auto upper_it = lower_it;

for (; upper_it != end; upper_it++)
{
if (upper_it->size() != lower_it->size())
{
break;
}
}

return helper::arrayElement(lower_it, upper_it);
}
}
40 changes: 1 addition & 39 deletions src/modules/word.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,14 @@
#include "faker-cxx/word.h"

#include <algorithm>
#include <array>
#include <optional>
#include <string>
#include <string_view>

#include "faker-cxx/helper.h"
#include "faker-cxx/word.h"
#include "word_data.h"

namespace faker::word
{
template <typename It>
auto sortedSizeArrayElement(std::optional<unsigned int> length, It start, It end) -> decltype(*std::declval<It>())
{
if (!length)
{
return helper::arrayElement(start, end);
}

size_t length_64 = *length;
auto lower_it = ::std::lower_bound(start, end, length_64,
[](const auto& lhs, const auto& value) { return lhs.size() < value; });

if (lower_it == end)
{
return helper::arrayElement(start, end);
}

if (lower_it->size() != length)
{
return helper::arrayElement(start, end);
}

auto upper_it = lower_it;

for (; upper_it != end; upper_it++)
{
if (upper_it->size() != lower_it->size())
{

break;
}
}

return helper::arrayElement(lower_it, upper_it);
}

std::string_view sample(std::optional<unsigned int> length)
{
return sortedSizeArrayElement(length, _allWords.cbegin(), _allWords.cend());
Expand Down
10 changes: 10 additions & 0 deletions tests/modules/word_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,14 @@ TEST_F(WordTest, shouldGenerateLargeNumberOfWords)
for (const auto& word : separatedWords) {
ASSERT_TRUE(std::ranges::find(_allWords, word) != _allWords.end());
}
}

TEST_F(WordTest, returnsRandomElementWhenNoExactLengthMatch)
{
std::vector<std::string> words = {"one", "three", "five"};
std::optional<unsigned int> length = 6;

auto result = sortedSizeArrayElement(length, words.begin(), words.end());

ASSERT_TRUE(result == "one" || result == "three" || result == "five");
}

0 comments on commit eacbf70

Please sign in to comment.