Skip to content

Commit

Permalink
refactor: code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
abdes committed Aug 20, 2022
1 parent b3faf8e commit 4fbee0a
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 186 deletions.
4 changes: 2 additions & 2 deletions textwrap/include/textwrap/textwrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@

#pragma once

#include <textwrap/asap_textwrap_export.h>

#include <optional>
#include <string>
#include <vector>

#include <textwrap/asap_textwrap_export.h>

/// Text wrapper public interface.
namespace asap::wrap {

Expand Down
46 changes: 24 additions & 22 deletions textwrap/src/textwrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/

#include "textwrap/textwrap.h"
#include "tokenizer.h"

#include <cstddef>
#include <iostream>
Expand All @@ -20,6 +19,8 @@
#include <optional>
#include <utility>

#include "tokenizer.h"

auto asap::wrap::operator<<(std::ostream &out,
const asap::wrap::TextWrapper &wrapper) -> std::ostream & {
out << "{w:" << wrapper.width_ << ",t:'" << wrapper.tab_
Expand All @@ -36,18 +37,12 @@ auto WrapChunks(const std::vector<asap::wrap::detail::Token> &chunks,

// https://www.geeksforgeeks.org/word-wrap-problem-space-optimized-solution/

auto num_chunks = chunks.size();
auto first_line_width = width - initial_indent.size();
auto other_line_witdh = width - indent.size();

size_t cur_chunk = 0;
size_t cur_chunk_in_line = 0;

// Variable to store number of characters in given line.
size_t currlen = 0;
const auto num_chunks = chunks.size();
const auto first_line_width = width - initial_indent.size();
const auto other_line_width = width - indent.size();

// Variable to store possible minimum cost of line.
size_t cost = 0;
size_t cur_chunk{0};
size_t cur_chunk_in_line{0};

// Table in which costs[index] represents cost of line starting with word
// chunks[index].
Expand All @@ -64,14 +59,21 @@ auto WrapChunks(const std::vector<asap::wrap::detail::Token> &chunks,
optimized[num_chunks - 1] = num_chunks - 1;

if (num_chunks > 1) {

// Variable to store possible minimum cost of line.
size_t cost{0};

// Make each word first word of line by iterating over each index in arr.
cur_chunk = num_chunks - 1;
do {
cur_chunk--;
currlen = 0;

// Variable to store number of characters in given line.
size_t currlen{0};

costs[cur_chunk] = std::numeric_limits<size_t>::max();
auto adjusted_width =
(cur_chunk == 0 ? first_line_width : other_line_witdh);
const auto adjusted_width =
(cur_chunk == 0 ? first_line_width : other_line_width);

cur_chunk_in_line = cur_chunk;
if (trim_lines) {
Expand All @@ -81,7 +83,7 @@ auto WrapChunks(const std::vector<asap::wrap::detail::Token> &chunks,
cur_chunk_in_line++;
}
}
auto first_chunk_in_line = cur_chunk_in_line;
const auto first_chunk_in_line = cur_chunk_in_line;
// Keep on adding words in current line by iterating from starting word
// up to last word in arr.
while (cur_chunk_in_line < num_chunks) {
Expand Down Expand Up @@ -175,14 +177,14 @@ void MoveAppend(std::vector<std::string> src, std::vector<std::string> &dst) {

[[nodiscard]] auto asap::wrap::TextWrapper::Wrap(const std::string &str) const
-> std::optional<std::vector<std::string>> {
auto tokenizer =
const auto tokenizer =
detail::Tokenizer(tab_, replace_ws_, collapse_ws_, break_on_hyphens_);

std::vector<std::string> result;
std::vector<detail::Token> chunks;
detail::TokenConsumer consume_token = [&chunks, this, &result](
detail::TokenType token_type,
std::string token) -> void {
const detail::TokenConsumer consume_token = [&chunks, this, &result](
detail::TokenType token_type,
std::string token) -> void {
if ((token_type == detail::TokenType::ParagraphMark ||
token_type == detail::TokenType::EndOfInput) &&
!chunks.empty()) {
Expand All @@ -207,11 +209,11 @@ void MoveAppend(std::vector<std::string> src, std::vector<std::string> &dst) {
[[nodiscard]] auto asap::wrap::TextWrapper::Fill(const std::string &str) const
-> std::optional<std::string> {

auto wrap_opt = Wrap(str);
const auto wrap_opt = Wrap(str);
if (!wrap_opt) {
return {};
}
auto wrap = wrap_opt.value();
const auto &wrap = wrap_opt.value();
std::string result;
auto size = std::accumulate(wrap.cbegin(), wrap.cend(),
static_cast<size_t>(0), [](size_t acc, const std::string &line) {
Expand Down
23 changes: 12 additions & 11 deletions textwrap/src/tokenizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@

#include "tokenizer.h"

#include <common/compilers.h>
#include <fsm/fsm.h>

#include <magic_enum.hpp>

#include <algorithm>
#include <numeric>
#include <utility>

#include <magic_enum.hpp>

#include <fsm/fsm.h>

using asap::fsm::ByDefault;
using asap::fsm::Continue;
using asap::fsm::DoNothing;
Expand Down Expand Up @@ -156,7 +155,7 @@ struct FinalState : public Will<ByDefault<DoNothing>> {
: consume_token_{std::move(callback)} {
}

auto OnEnter(const InputEnd & /*event*/) -> Status {
[[maybe_unused]] auto OnEnter(const InputEnd & /*event*/) -> Status {
consume_token_(TokenType::EndOfInput, "");
return Terminate{};
}
Expand Down Expand Up @@ -197,7 +196,8 @@ struct WordState : public Will<On<InputEnd, TransitionTo<FinalState>>,
break_on_hyphens} {
}

static auto OnEnter(const NonWhiteSpaceChar & /*event*/) -> Status {
[[maybe_unused]] static auto OnEnter(const NonWhiteSpaceChar & /*event*/)
-> Status {
return ReissueEvent{};
}

Expand All @@ -208,7 +208,7 @@ struct WordState : public Will<On<InputEnd, TransitionTo<FinalState>>,
return Continue{};
}

auto Handle(const NonWhiteSpaceChar &event) -> DoNothing {
[[maybe_unused]] auto Handle(const NonWhiteSpaceChar &event) -> DoNothing {
if (break_on_hyphens_ && event.value == '-' && !token_.empty() &&
(std::isalpha(token_.back()) != 0)) {
token_.push_back(event.value);
Expand Down Expand Up @@ -246,7 +246,8 @@ struct WhiteSpaceState : public Will<On<InputEnd, TransitionTo<FinalState>>,
collapse_ws_{collapse_ws} {
}

static auto OnEnter(const WhiteSpaceChar & /*event*/) -> Status {
[[maybe_unused]] static auto OnEnter(const WhiteSpaceChar & /*event*/)
-> Status {
return ReissueEvent{};
}

Expand All @@ -259,7 +260,7 @@ struct WhiteSpaceState : public Will<On<InputEnd, TransitionTo<FinalState>>,
return Continue{};
}

auto Handle(const WhiteSpaceChar &event) -> DoNothing {
[[maybe_unused]] auto Handle(const WhiteSpaceChar &event) -> DoNothing {
if (event.value == '\n') {
if (last_was_newline_) {
token_.pop_back();
Expand Down Expand Up @@ -379,7 +380,7 @@ auto asap::wrap::detail::Tokenizer::Tokenize(
reissue = false;
// reuse the same token again
} else {
cursor++;
++cursor;
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions textwrap/src/tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@

#pragma once

#include <textwrap/asap_textwrap_export.h>

#include <functional>
#include <iostream>
#include <vector>

#include <textwrap/asap_textwrap_export.h>

/// Internal implementation details for the text wrapper.
namespace asap::wrap::detail {
Expand Down
36 changes: 9 additions & 27 deletions textwrap/test/textwrapper_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,8 @@

#include "textwrap/textwrap.h"

#include <common/compilers.h>

#include <gtest/gtest.h>

#include <type_traits>

// Disable compiler and linter warnings originating from the unit test framework
// and for which we cannot do anything. Additionally, every TEST or TEST_X macro
// usage must be preceded by a '// NOLINTNEXTLINE'.
ASAP_DIAGNOSTIC_PUSH
#if defined(__clang__) && ASAP_HAS_WARNING("-Wused-but-marked-unused")
#pragma clang diagnostic ignored "-Wused-but-marked-unused"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wunused-member-function"
#endif
// NOLINTBEGIN(used-but-marked-unused)

namespace asap::wrap {

namespace {
Expand All @@ -36,15 +21,15 @@ TEST(TextWrapper, WrapExample) {
"of a wife.";

constexpr size_t column_width = 28;
TextWrapper title_wrapper = TextWrapper::Create().Width(column_width);
TextWrapper text_wrapper = TextWrapper::Create()
.Width(column_width)
.TrimLines()
.ReplaceWhiteSpace()
.CollapseWhiteSpace()
.IndentWith()
.Initially(" ")
.Then(" ");
const TextWrapper title_wrapper = TextWrapper::Create().Width(column_width);
const TextWrapper text_wrapper = TextWrapper::Create()
.Width(column_width)
.TrimLines()
.ReplaceWhiteSpace()
.CollapseWhiteSpace()
.IndentWith()
.Initially(" ")
.Then(" ");

std::cout << title_wrapper.Fill(book).value_or("error") << std::endl;
std::cout << text_wrapper.Fill(passage).value_or("error") << std::endl;
Expand All @@ -62,6 +47,3 @@ TEST(TextWrapper, WrapExample) {
} // namespace

} // namespace asap::wrap

// NOLINTEND(used-but-marked-unused)
ASAP_DIAGNOSTIC_POP
28 changes: 8 additions & 20 deletions textwrap/test/textwrapper_random_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,13 @@

#include "textwrap/textwrap.h"

#include <common/compilers.h>
#include <array>
#include <random>

#include "gmock/gmock.h"
#include <gtest/gtest.h>

#include <array>
#include <random>

// Disable compiler and linter warnings originating from the unit test framework
// and for which we cannot do anything. Additionally, every TEST or TEST_X macro
// usage must be preceded by a '// NOLINTNEXTLINE'.
ASAP_DIAGNOSTIC_PUSH
#if defined(__clang__) && ASAP_HAS_WARNING("-Wused-but-marked-unused")
#pragma clang diagnostic ignored "-Wused-but-marked-unused"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wunused-member-function"
#endif
// NOLINTBEGIN(used-but-marked-unused)
#include <common/compilers.h>

using ::testing::IsTrue;

Expand All @@ -43,8 +32,8 @@ auto RandomWordChar() -> char {
return static_cast<char>(word_char_generator(rng));
}
auto RandomWhiteSpace() -> char {
static const auto white_space = std::array<const char, 14>{' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', '\t', '\v', '\f', '\r', '\n'};
static constexpr auto white_space = std::array<const char, 14>{{' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', '\t', '\v', '\f', '\r', '\n'}};
return (white_space.at(ws_generator(rng)));
}
auto GenerateWord(size_t length) -> std::string {
Expand Down Expand Up @@ -77,6 +66,8 @@ auto GenerateText(size_t words) -> std::string {
case 4:
text += ".";
break;
default:
ASAP_UNREACHABLE();
}
text += GenerateWhiteSpace(ws_size_generator(rng));
}
Expand Down Expand Up @@ -113,7 +104,7 @@ TEST(TextWrapper, RandomTests) {
clock.tick();
for (size_t i = 1; i < maximum_text_length; ++i) {
auto text = GenerateText(i);
auto size = text.size();
const auto size = text.size();
for (size_t column_width = 3; column_width < size; ++column_width) {
TextWrapper text_wrapper = TextWrapper::Create()
.Width(column_width)
Expand All @@ -131,6 +122,3 @@ TEST(TextWrapper, RandomTests) {
} // namespace

} // namespace asap::wrap

// NOLINTEND(used-but-marked-unused)
ASAP_DIAGNOSTIC_POP
Loading

0 comments on commit 4fbee0a

Please sign in to comment.