mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
Merge pull request #1 from enduro2d/feature/format_str_view
strings::format string view support
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "_base.hpp"
|
||||
|
||||
#include "configs.hpp"
|
||||
#include "macros.hpp"
|
||||
#include "stdex.hpp"
|
||||
|
||||
@@ -398,6 +398,10 @@ namespace e2d { namespace stdex
|
||||
size_type size_ = 0;
|
||||
};
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
const typename basic_string_view<Char, Traits>::size_type
|
||||
basic_string_view<Char, Traits>::npos;
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
basic_string_view<Char, Traits> l,
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
#include "streams.hpp"
|
||||
#include "strfmts.hpp"
|
||||
#include "strings.hpp"
|
||||
#include "strings.inl"
|
||||
#include "time.hpp"
|
||||
|
||||
@@ -353,6 +353,13 @@ namespace e2d { namespace strings
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class format_arg<str_view> : public format_arg<str> {
|
||||
public:
|
||||
explicit format_arg(str_view sv)
|
||||
: format_arg<str>(sv) {}
|
||||
};
|
||||
|
||||
//
|
||||
// wstr
|
||||
//
|
||||
@@ -372,6 +379,13 @@ namespace e2d { namespace strings
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class format_arg<wstr_view> : public format_arg<wstr> {
|
||||
public:
|
||||
explicit format_arg(wstr_view sv)
|
||||
: format_arg<wstr>(sv) {}
|
||||
};
|
||||
|
||||
//
|
||||
// str16
|
||||
//
|
||||
@@ -391,6 +405,13 @@ namespace e2d { namespace strings
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class format_arg<str16_view> : public format_arg<str16> {
|
||||
public:
|
||||
explicit format_arg(str16_view sv)
|
||||
: format_arg<str16>(sv) {}
|
||||
};
|
||||
|
||||
//
|
||||
// str32
|
||||
//
|
||||
@@ -410,6 +431,13 @@ namespace e2d { namespace strings
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class format_arg<str32_view> : public format_arg<str32> {
|
||||
public:
|
||||
explicit format_arg(str32_view sv)
|
||||
: format_arg<str32>(sv) {}
|
||||
};
|
||||
|
||||
//
|
||||
// color
|
||||
//
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace e2d
|
||||
template < typename... Args >
|
||||
std::size_t format(
|
||||
char* dst, std::size_t size,
|
||||
const char* fmt, Args&&... args);
|
||||
str_view fmt, Args&&... args);
|
||||
|
||||
template < typename... Args >
|
||||
str rformat(const char* fmt, Args&&... args);
|
||||
str rformat(str_view fmt, Args&&... args);
|
||||
|
||||
bool wildcard_match(str_view string, str_view pattern);
|
||||
}
|
||||
|
||||
@@ -238,8 +238,10 @@ namespace e2d { namespace strings
|
||||
|
||||
template < typename Tuple >
|
||||
std::enable_if_t<std::tuple_size<Tuple>::value <= 10, std::size_t>
|
||||
format_impl(char* dst, std::size_t size, const char* format, const Tuple& targs) {
|
||||
if ( !format ) {
|
||||
format_impl(char* dst, std::size_t size, str_view fmt, const Tuple& targs) {
|
||||
const char* format_i = fmt.cbegin();
|
||||
const char* const format_e = fmt.cend();
|
||||
if ( !format_i ) {
|
||||
throw bad_format();
|
||||
}
|
||||
if ( !dst != !size ) {
|
||||
@@ -248,20 +250,19 @@ namespace e2d { namespace strings
|
||||
std::size_t result = 0;
|
||||
const char* const b_dst = dst;
|
||||
const char* const e_dst = b_dst ? b_dst + size : nullptr;
|
||||
while ( *format ) {
|
||||
while ( format_i != format_e ) {
|
||||
if ( dst && dst == e_dst - 1 ) {
|
||||
*dst = '\0';
|
||||
throw bad_format_buffer();
|
||||
}
|
||||
if ( *format != '%' ) {
|
||||
if ( *format_i != '%' ) {
|
||||
if ( dst ) {
|
||||
*dst++ = *format;
|
||||
*dst++ = *format_i;
|
||||
}
|
||||
++result;
|
||||
++format;
|
||||
++format_i;
|
||||
} else {
|
||||
const char n_param = *(++format);
|
||||
if ( !n_param ) {
|
||||
if ( ++format_i == format_e ) {
|
||||
// "hello%"
|
||||
if ( dst ) {
|
||||
*dst = '\0';
|
||||
@@ -273,7 +274,7 @@ namespace e2d { namespace strings
|
||||
? math::numeric_cast<std::size_t>(e_dst - dst)
|
||||
: 0;
|
||||
E2D_ASSERT(!dst || dst_tail_size);
|
||||
switch ( n_param ) {
|
||||
switch ( *format_i ) {
|
||||
case '0' :
|
||||
write_arg_r = write_arg_n<0>(dst, dst_tail_size, targs);
|
||||
break;
|
||||
@@ -337,7 +338,7 @@ namespace e2d { namespace strings
|
||||
dst += write_bytes;
|
||||
}
|
||||
result += write_bytes;
|
||||
++format;
|
||||
++format_i;
|
||||
}
|
||||
}
|
||||
if ( dst ) {
|
||||
@@ -353,7 +354,7 @@ namespace e2d { namespace strings
|
||||
template < typename... Args >
|
||||
std::size_t format(
|
||||
char* dst, std::size_t size,
|
||||
const char* fmt, Args&&... args)
|
||||
str_view fmt, Args&&... args)
|
||||
{
|
||||
return impl::format_impl(
|
||||
dst, size, fmt,
|
||||
@@ -361,7 +362,7 @@ namespace e2d { namespace strings
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
str rformat(const char* fmt, Args&&... args) {
|
||||
str rformat(str_view fmt, Args&&... args) {
|
||||
auto targs = std::make_tuple(
|
||||
impl::wrap_arg(std::forward<Args>(args))...);
|
||||
const std::size_t expected_format_size = impl::format_impl(
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace
|
||||
dst.assign(img_size, img_format, std::move(img_buffer));
|
||||
return true;
|
||||
}
|
||||
} catch (std::exception&) {
|
||||
} catch (...) {
|
||||
// nothing
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -7,6 +7,16 @@
|
||||
#include "_utils.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* null_utf8 = nullptr;
|
||||
const wchar_t* null_wide = nullptr;
|
||||
const char16_t* null_utf16 = nullptr;
|
||||
const char32_t* null_utf32 = nullptr;
|
||||
|
||||
str_view null_view = {null_utf8, 0};
|
||||
}
|
||||
|
||||
TEST_CASE("strings") {
|
||||
{
|
||||
REQUIRE(make_utf8("hello") == "hello");
|
||||
@@ -30,11 +40,6 @@ TEST_CASE("strings") {
|
||||
REQUIRE(make_utf32(U"hello") == U"hello");
|
||||
}
|
||||
{
|
||||
const char* null_utf8 = nullptr;
|
||||
const wchar_t* null_wide = nullptr;
|
||||
const char16_t* null_utf16 = nullptr;
|
||||
const char32_t* null_utf32 = nullptr;
|
||||
|
||||
REQUIRE(make_utf8(str_view(null_utf8, 0)) == make_utf8(u""));
|
||||
REQUIRE(make_utf8(wstr_view(null_wide, 0)) == make_utf8(L""));
|
||||
REQUIRE(make_utf8(str16_view(null_utf16, 0)) == make_utf8(u""));
|
||||
@@ -95,8 +100,6 @@ TEST_CASE("strings") {
|
||||
REQUIRE(wildcard_match("", "*") == true);
|
||||
REQUIRE(wildcard_match("", "?") == false);
|
||||
|
||||
const char* null_utf8 = nullptr;
|
||||
str_view null_view = {null_utf8, 0};
|
||||
REQUIRE(wildcard_match(null_view, null_view) == true);
|
||||
REQUIRE(wildcard_match("a", null_view) == false);
|
||||
REQUIRE(wildcard_match(null_view, "*") == true);
|
||||
@@ -214,7 +217,6 @@ TEST_CASE("strings") {
|
||||
}
|
||||
{
|
||||
char buf[6];
|
||||
REQUIRE_THROWS_AS(strings::format(buf, sizeof(buf), nullptr), strings::bad_format);
|
||||
REQUIRE_THROWS_AS(strings::format(buf, 0, "hello"), strings::bad_format_buffer);
|
||||
REQUIRE_THROWS_AS(strings::format(nullptr, sizeof(buf), "hello"), strings::bad_format_buffer);
|
||||
REQUIRE_THROWS_AS(strings::format(buf, sizeof(buf), "helloE"), strings::bad_format_buffer);
|
||||
@@ -235,8 +237,6 @@ TEST_CASE("strings") {
|
||||
REQUIRE_THROWS_AS(strings::format(buf, sizeof(buf), "%z%hell"), strings::bad_format);
|
||||
}
|
||||
{
|
||||
REQUIRE_THROWS_AS(strings::rformat(nullptr), strings::bad_format);
|
||||
|
||||
REQUIRE_THROWS_AS(strings::rformat("%"), strings::bad_format);
|
||||
REQUIRE_THROWS_AS(strings::rformat("%hell"), strings::bad_format);
|
||||
REQUIRE_THROWS_AS(strings::rformat("he%ll"), strings::bad_format);
|
||||
@@ -250,6 +250,20 @@ TEST_CASE("strings") {
|
||||
REQUIRE_THROWS_AS(strings::rformat("hell%y%"), strings::bad_format);
|
||||
REQUIRE_THROWS_AS(strings::rformat("%z%hell"), strings::bad_format);
|
||||
}
|
||||
{
|
||||
REQUIRE(strings::rformat(str_view("%0"), 42) == "42");
|
||||
REQUIRE(strings::rformat(str_view("%0%1",2), 42) == "42");
|
||||
|
||||
auto s1 = make_utf8("hello");
|
||||
auto s2 = make_wide("hello");
|
||||
auto s3 = make_utf16("hello");
|
||||
auto s4 = make_utf32("hello");
|
||||
|
||||
REQUIRE(strings::rformat(str_view("%0"), str_view(s1)) == "hello");
|
||||
REQUIRE(strings::rformat(str_view("%0"), wstr_view(s2)) == "hello");
|
||||
REQUIRE(strings::rformat(str_view("%0"), str16_view(s3)) == "hello");
|
||||
REQUIRE(strings::rformat(str_view("%0"), str32_view(s4)) == "hello");
|
||||
}
|
||||
{
|
||||
char buf[1];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user