Skip to content

Commit

Permalink
Move string utilities to base
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Oct 19, 2024
1 parent 0c219c7 commit 5bfe7e5
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 72 deletions.
3 changes: 2 additions & 1 deletion source/base/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ add_library(tactile::base ALIAS tactile-base)
target_sources(tactile-base
INTERFACE FILE_SET "HEADERS" BASE_DIRS "inc" FILES
"inc/tactile/base/container/buffer.hpp"
"inc/tactile/base/container/string_map.hpp"
"inc/tactile/base/container/lookup.hpp"
"inc/tactile/base/container/string.hpp"
"inc/tactile/base/container/string_map.hpp"
"inc/tactile/base/document/component_view.hpp"
"inc/tactile/base/document/document.hpp"
"inc/tactile/base/document/document_visitor.hpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,50 @@

#pragma once

#include <algorithm> // find_if
#include <cctype> // isspace
#include <locale> // locale
#include <string> // string
#include <string_view> // string_view

#include "tactile/base/prelude.hpp"
#include "tactile/base/util/concepts.hpp"

namespace tactile::core {
namespace tactile {

/**
* Removes leading and trailing spaces from a given string.
*
* \note
* This function will only modify strings that have at least one non-space
* character.
* Only strings with at least one non-space character are modified.
*
* \param str The string to trim.
*
* \return
* A trimmed string.
*/
[[nodiscard]]
auto trim_string(std::string_view str) -> std::string;
constexpr auto trim_string(const std::string_view str) -> std::string
{
std::string trimmed {str};

const auto find_first_non_space = [](const auto begin, const auto end) {
return std::find_if(begin, end, [](const char ch) {
return !std::isspace(ch, std::locale::classic());
});
};

const auto left = find_first_non_space(trimmed.begin(), trimmed.end());
if (left != trimmed.end()) {
trimmed.erase(trimmed.begin(), left);
}

const auto right = find_first_non_space(trimmed.rbegin(), trimmed.rend());
if (right != trimmed.rend()) {
trimmed.erase(right.base(), trimmed.end());
}

return trimmed;
}

/**
* Splits a string into a collection of tokens separated by a given character.
Expand All @@ -32,15 +54,16 @@ auto trim_string(std::string_view str) -> std::string;
*
* \param str The full string.
* \param separator The character to use as the separator.
* \param callback A callback invoked for each token in the string. The
* function will return immediately if the callback returns
* false.
* \param callback A callback invoked for each token in the string. The function will return
* immediately if this callback returns false.
*
* \return
* True if the function completed without returning early; false otherwise.
*/
template <InvocableType<bool, std::string_view> T>
auto split_string(const std::string_view str, const char separator, const T& callback) -> bool
constexpr auto visit_tokens(const std::string_view str,
const char separator,
const T& callback) -> bool
{
std::size_t pos = 0;
const auto str_length = str.size();
Expand Down Expand Up @@ -71,4 +94,4 @@ auto split_string(const std::string_view str, const char separator, const T& cal
return true;
}

} // namespace tactile::core
} // namespace tactile
1 change: 1 addition & 0 deletions source/base/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_executable(tactile-base-test)
target_sources(tactile-base-test
PRIVATE
"src/container/lookup_test.cpp"
"src/container/string_test.cpp"
"src/io/int_parser_test.cpp"
"src/io/tile_io_test.cpp"
"src/meta/attribute_test.cpp"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#include "tactile/core/util/string_ops.hpp"
#include "tactile/base/container/string.hpp"

#include <vector> // vector

#include <gtest/gtest.h>

namespace tactile::core {
namespace tactile {
namespace {

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringEmpty)
// tactile::visit_tokens
TEST(String, VisitTokensEmpty)
{
std::vector<std::string> tokens {};
split_string("", '!', [&tokens](const std::string_view token) {
visit_tokens("", '!', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});

EXPECT_EQ(tokens.size(), 0);
}

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringLetters)
// tactile::visit_tokens
TEST(String, VisitTokensLetters)
{
std::vector<std::string> tokens {};
split_string("a:b:c:d", ':', [&tokens](const std::string_view token) {
visit_tokens("a:b:c:d", ':', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});
Expand All @@ -36,11 +37,11 @@ TEST(StringOps, SplitStringLetters)
EXPECT_EQ(tokens.at(3), "d");
}

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringNumbers)
// tactile::visit_tokens
TEST(String, VisitTokensNumbers)
{
std::vector<std::string> tokens {};
split_string("1 200 30 4000", ' ', [&tokens](const std::string_view token) {
visit_tokens("1 200 30 4000", ' ', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});
Expand All @@ -52,11 +53,11 @@ TEST(StringOps, SplitStringNumbers)
EXPECT_EQ(tokens.at(3), "4000");
}

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringWithLeadingSeparator)
// tactile::visit_tokens
TEST(String, VisitTokensWithLeadingSeparator)
{
std::vector<std::string> tokens {};
split_string(".woah", '.', [&tokens](const std::string_view token) {
visit_tokens(".woah", '.', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});
Expand All @@ -66,11 +67,11 @@ TEST(StringOps, SplitStringWithLeadingSeparator)
EXPECT_EQ(tokens.at(1), "woah");
}

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringWithTrailingSeparator)
// tactile::visit_tokens
TEST(String, VisitTokensWithTrailingSeparator)
{
std::vector<std::string> tokens {};
split_string("foobar!", '!', [&tokens](const std::string_view token) {
visit_tokens("foobar!", '!', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});
Expand All @@ -79,11 +80,11 @@ TEST(StringOps, SplitStringWithTrailingSeparator)
EXPECT_EQ(tokens.at(0), "foobar");
}

/// \trace tactile::core::split_string
TEST(StringOps, SplitStringWithEmptyTokens)
// tactile::visit_tokens
TEST(String, VisitTokensWithEmptyTokens)
{
std::vector<std::string> tokens {};
split_string("aaa::a:bb::c", ':', [&tokens](const std::string_view token) {
visit_tokens("aaa::a:bb::c", ':', [&tokens](const std::string_view token) {
tokens.emplace_back(token);
return true;
});
Expand All @@ -97,8 +98,8 @@ TEST(StringOps, SplitStringWithEmptyTokens)
EXPECT_EQ(tokens.at(5), "c");
}

/// \trace tactile::core::trim_string
TEST(StringOps, TrimString)
// tactile::trim_string
TEST(String, TrimString)
{
EXPECT_EQ(trim_string(" "), " ");
EXPECT_EQ(trim_string(" "), " ");
Expand All @@ -111,4 +112,5 @@ TEST(StringOps, TrimString)
EXPECT_EQ(trim_string(" a b c d "), "a b c d");
}

} // namespace tactile::core
} // namespace
} // namespace tactile
2 changes: 0 additions & 2 deletions source/core/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ target_sources(tactile-core
"src/ui/viewport.cpp"
"src/ui/widget_manager.cpp"
"src/util/string_conv.cpp"
"src/util/string_ops.cpp"
"src/util/uuid.cpp"
"src/tactile_app.cpp"

Expand Down Expand Up @@ -232,7 +231,6 @@ target_sources(tactile-core
"inc/tactile/core/ui/viewport.hpp"
"inc/tactile/core/ui/widget_manager.hpp"
"inc/tactile/core/util/string_conv.hpp"
"inc/tactile/core/util/string_ops.hpp"
"inc/tactile/core/util/uuid.hpp"
"inc/tactile/core/tactile_app.hpp"
)
Expand Down
2 changes: 1 addition & 1 deletion source/core/lib/src/io/ini.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include <string> // getline
#include <utility> // move

#include "tactile/base/container/string.hpp"
#include "tactile/core/debug/assert.hpp"
#include "tactile/core/log/logger.hpp"
#include "tactile/core/log/set_log_scope.hpp"
#include "tactile/core/util/string_ops.hpp"

namespace tactile::core {
namespace {
Expand Down
34 changes: 0 additions & 34 deletions source/core/lib/src/util/string_ops.cpp

This file was deleted.

1 change: 0 additions & 1 deletion source/core/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ target_sources(tactile-core-test
"src/ui/imgui_compat_test.cpp"
"src/ui/viewport_test.cpp"
"src/util/string_conv_test.cpp"
"src/util/string_ops_test.cpp"
"src/util/uuid_test.cpp"
"src/ir_comparison.cpp"
"src/main.cpp"
Expand Down

0 comments on commit 5bfe7e5

Please sign in to comment.