Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
project(EduceLabCore VERSION 0.2.1)
project(EduceLabCore VERSION 0.3.0)

# Setup project directories
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
Expand Down
35 changes: 35 additions & 0 deletions include/educelab/core/utils/String.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include <algorithm>
#include <charconv>
#include <exception>
#include <iomanip>
#include <locale>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
Expand Down Expand Up @@ -189,6 +191,39 @@ static auto split(std::string_view s, const Ds&... ds)
return tokens;
}

/** @brief Partition a string by a separator substring */
static auto partition(std::string_view s, const std::string_view sep)
-> std::tuple<std::string_view, std::string_view, std::string_view>
{
// Find the starting position
const auto startPos = s.find(sep);

// Didn't find the delimiter
if (startPos == std::string::npos) {
return {s, "", ""};
}

// Split into parts
auto pre = s.substr(0, startPos);
auto mid = s.substr(startPos, sep.size());
auto post = s.substr(startPos + sep.size());

// Return the parts
return {pre, mid, post};
}

/** @brief Convert an Integer to a padded string */
template <
typename Integer,
std::enable_if_t<std::is_integral_v<Integer>, bool> = true>
auto to_padded_string(Integer val, const int padding, const char fill = '0')
-> std::string
{
std::stringstream stream;
stream << std::setw(padding) << std::setfill(fill) << val;
return stream.str();
}

/**
* @brief Convert a string to a numeric type.
*
Expand Down
50 changes: 42 additions & 8 deletions tests/src/TestString.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <gtest/gtest.h>

#include <string>
#include <tuple>

#include "educelab/core/utils/String.hpp"

Expand Down Expand Up @@ -151,17 +152,50 @@ TEST(String, Split)
EXPECT_EQ(split("This is only a test."), expected);
}

TEST(String, Partition)
{
// key=value
const auto [p0, m0, s0] = partition("key=value", "=");
EXPECT_EQ(p0, "key");
EXPECT_EQ(m0, "=");
EXPECT_EQ(s0, "value");

// {} replacement
const auto [p1, m1, s1] = partition("prefix{}suffix", "{}");
EXPECT_EQ(p1, "prefix");
EXPECT_EQ(m1, "{}");
EXPECT_EQ(s1, "suffix");

// to existing strings
std::string p2, m2, s2;
std::tie(p2, m2, s2) = partition("abc", "b");
EXPECT_EQ(p2, "a");
EXPECT_EQ(m2, "b");
EXPECT_EQ(s2, "c");
}

TEST(String, ToPaddedString)
{
// zero-pad (default)
EXPECT_EQ(to_padded_string(5, 3), "005");
EXPECT_EQ(to_padded_string(5, 10), "0000000005");

// zero-pad (custom)
EXPECT_EQ(to_padded_string(5, 3, '5'), "555");
EXPECT_EQ(to_padded_string(5, 3, 'x'), "xx5");
}

TEST(String, ToNumeric)
{
std::string test{"100.3456 unparsed"};
EXPECT_EQ(to_numeric<int8_t>(test), int8_t(100));
EXPECT_EQ(to_numeric<uint8_t>(test), uint8_t(100));
EXPECT_EQ(to_numeric<int16_t>(test), int16_t(100));
EXPECT_EQ(to_numeric<uint16_t>(test), uint16_t(100));
EXPECT_EQ(to_numeric<int32_t>(test), int32_t(100));
EXPECT_EQ(to_numeric<uint32_t>(test), uint32_t(100));
EXPECT_EQ(to_numeric<int64_t>(test), int64_t(100));
EXPECT_EQ(to_numeric<uint64_t>(test), uint64_t(100));
EXPECT_EQ(to_numeric<int8_t>(test), std::int8_t{100});
EXPECT_EQ(to_numeric<uint8_t>(test), std::uint8_t{100});
EXPECT_EQ(to_numeric<int16_t>(test), std::int16_t{100});
EXPECT_EQ(to_numeric<uint16_t>(test), std::uint16_t{100});
EXPECT_EQ(to_numeric<int32_t>(test), std::int32_t{100});
EXPECT_EQ(to_numeric<uint32_t>(test), std::uint32_t{100});
EXPECT_EQ(to_numeric<int64_t>(test), std::int64_t{100});
EXPECT_EQ(to_numeric<uint64_t>(test), std::uint64_t{100});

EXPECT_EQ(to_numeric<float>(test), 100.3456F);
EXPECT_EQ(to_numeric<double>(test), 100.3456);
Expand Down