Skip to content
Closed
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
101 changes: 101 additions & 0 deletions benchmark/0015.string/trim_right.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@

#include <fast_io_dsal/string.h>
#include <fast_io.h>
#include <fast_io_device.h>
#include <fast_io_driver/timer.h>
#include <cassert>
using namespace fast_io::io;

namespace fast_io
{

/// Trims whitespace characters from the end of a fast_io::basic_string
/// @tparam CharT Character type (must be std::integral)
/// @tparam Allocator Allocator type (defaults to native_global_allocator)
/// @param str The string to trim (modified in-place)
/// @return Reference to the modified string
template <::std::integral CharT, typename Allocator = native_global_allocator>
inline constexpr basic_string<CharT, Allocator> &
trim_right(basic_string<CharT, Allocator> &str) noexcept
{
if (str.empty())
{
return str;
}

auto first = str.data();
auto last = str.data() + str.size();

// Find the position after the last non-whitespace character
CharT const *trim_pos = last;
CharT const *current = first;

while (current < last)
{
// Find next whitespace character
auto next_space = details::find_space_common_impl<false, false>(current, last);
if (next_space == last)
{
// No more whitespace characters found
trim_pos = last;
break;
}

// Find next non-whitespace character after the whitespace
auto next_non_space = details::find_space_common_impl<false, true>(next_space, last);
if (next_non_space == last)
{
// From next_space to end are all whitespace characters
trim_pos = next_space;
break;
}

current = next_non_space;
}

// Convert const pointer back to iterator for erase
auto trim_iterator = str.begin() + (trim_pos - first);
str.erase(trim_iterator, str.end());
return str;
}

} // namespace fast_io


int main()
{
{
constexpr std::size_t N(40000000);
{
fast_io::timer t(u8"trim_right string");
fast_io::string str(" ok someone like trim ok ");
for (std::size_t i{}; i != N; ++i)
{
str.push_back(' ');
str.push_back('\t');
str.push_back('\r');
str.push_back('\f');
str.push_back('\v');
str.push_back('\n');
}
assert(fast_io::trim_right(str) == fast_io::string(" ok someone like trim ok"));
}
}
{
constexpr std::size_t N(40000000);
{
fast_io::timer t(u8"trim_right u16string");
fast_io::u16string str(u" ok someone like trim ok ");
for (std::size_t i{}; i != N; ++i)
{
str.push_back(u' ');
str.push_back(u'\t');
str.push_back(u'\r');
str.push_back(u'\f');
str.push_back(u'\v');
str.push_back(u'\n');
}
assert(fast_io::trim_right(str) == fast_io::u16string(u" ok someone like trim ok"));
}
}
}
2 changes: 1 addition & 1 deletion include/fast_io_dsal/impl/freestanding.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ inline constexpr Iter2 overlapped_copy(Iter1 first, Iter1 last, Iter2 dest) noex
}
}

if (__builtin_is_constant_evaluated())
if (__builtin_is_constant_evaluated())
{
::fast_io::details::overlapped_copy_buffer_ptr<iter2valuetype> tempbuffer(static_cast<::std::size_t>(::std::distance(first, last)));
auto buffered{::std::copy(first, last, tempbuffer.ptr)};
Expand Down
30 changes: 15 additions & 15 deletions include/fast_io_dsal/impl/tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,33 +94,33 @@ tuple(Args &&...) -> tuple<Args...>;

template <::std::size_t I, typename... Args>
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> &self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> &self) noexcept
{
return static_cast<::fast_io::containers::details::tuple_element_impl_<I, ::fast_io::containers::details::pack_indexing_t_<I, Args...>> &>(self).val_;
}

template <::std::size_t I, typename... Args>
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> const &self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> const &self) noexcept
{
return static_cast<::fast_io::containers::details::tuple_element_impl_<I, ::fast_io::containers::details::pack_indexing_t_<I, Args...>> const &>(self).val_;
}

template <::std::size_t I, typename... Args>
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> &&self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> &&self) noexcept
{
return ::std::move(
static_cast<::fast_io::containers::details::tuple_element_impl_<I, ::fast_io::containers::details::pack_indexing_t_<I, Args...>> &&>(self).val_);
}

template <::std::size_t I, typename... Args>
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> const &&self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> const &&self) noexcept
{
return ::std::move(
static_cast<::fast_io::containers::details::tuple_element_impl_<I, ::fast_io::containers::details::pack_indexing_t_<I, Args...>> const &&>(self).val_);
Expand All @@ -147,17 +147,17 @@ constexpr auto get_tuple_element_by_type_() noexcept
template <typename T, typename... Args>
requires((::std::same_as<T, Args> + ...) == 1)
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> const &self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> const &self) noexcept
{
return static_cast<decltype(::fast_io::containers::details::get_tuple_element_by_type_<T, 0, Args...>())::type const &>(self).val_;
}

template <typename T, typename... Args>
requires((::std::same_as<T, Args> + ...) == 1)
FAST_IO_GNU_ALWAYS_INLINE
[[nodiscard]]
constexpr auto&& get(::fast_io::containers::tuple<Args...> const &&self) noexcept
[[nodiscard]]
constexpr auto &&get(::fast_io::containers::tuple<Args...> const &&self) noexcept
{
return ::std::move(
static_cast<decltype(::fast_io::containers::details::get_tuple_element_by_type_<T, 0, Args...>())::type const &&>(self).val_);
Expand All @@ -177,15 +177,15 @@ constexpr bool is_tuple_<tuple<Args...>> = true;
template <typename T>
concept is_tuple = ::fast_io::containers::details::is_tuple_<::std::remove_cvref_t<T>>;

template<typename... Args>
template <typename... Args>
[[nodiscard]]
constexpr auto forward_as_tuple(Args&&... args)
constexpr auto forward_as_tuple(Args &&...args)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-braces"
#endif
return ::fast_io::containers::tuple<Args&&...>(::std::forward<Args>(args)...);
return ::fast_io::containers::tuple<Args &&...>(::std::forward<Args>(args)...);
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
Expand Down