Merge pull request #1 from enduro2d/feature/format_str_view

strings::format string view support
This commit is contained in:
BlackMat MATov
2018-09-04 10:33:25 +03:00
committed by GitHub
8 changed files with 74 additions and 25 deletions

View File

@@ -7,6 +7,7 @@
#pragma once
#include "_base.hpp"
#include "configs.hpp"
#include "macros.hpp"
#include "stdex.hpp"

View File

@@ -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,

View File

@@ -17,4 +17,5 @@
#include "streams.hpp"
#include "strfmts.hpp"
#include "strings.hpp"
#include "strings.inl"
#include "time.hpp"

View File

@@ -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
//

View File

@@ -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);
}

View File

@@ -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(

View File

@@ -68,7 +68,7 @@ namespace
dst.assign(img_size, img_format, std::move(img_buffer));
return true;
}
} catch (std::exception&) {
} catch (...) {
// nothing
}
return false;

View File

@@ -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];