Skip to content

Commit

Permalink
(String) Add partition and to_padded_string (#4)
Browse files Browse the repository at this point in the history
Copy extra string functions from volume-cartographer.
  • Loading branch information
csparker247 authored Jun 28, 2024
1 parent 788da8c commit dff1fd8
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 9 deletions.
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

0 comments on commit dff1fd8

Please sign in to comment.