Alien-libpanda
view release on metacpan or search on metacpan
t/string_test.h view on Meta::CPAN
static T dest[100000];
auto s = mstr(data, count);
s.copy(dest, s.size());
dest[s.size()] = (T)0;
return dest;
}
// temporary return value, only immediate use, no assigments!
static basic_string_view<T> svstr (const char* data, size_t count = 1) {
return basic_string_view<T>(cstr(data, count));
}
static T* extstr (StdString src, size_t cap = 0) {
if (cap < src.size()) cap = src.size();
T* ext = (T*)malloc(cap * sizeof(T));
std::memcpy(ext, src.data(), cap * sizeof(T));
return ext;
}
static ExternalShared* shared_buf_alloc () {
return (ExternalShared*)panda::DynamicMemoryPool::instance()->allocate(sizeof(ExternalShared));
}
template <class U = String> static U create_external (StdString exp, size_t cap) { return U(extstr(exp), exp.size(), cap, &Allocator::ext_free); }
template <class U = String> static U create_external (StdString exp) { return create_external<U>(exp, exp.size()); }
template <class U = String> static U create_external_cbuf (StdString exp, size_t cap) { return U(extstr(exp), exp.size(), cap, &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free); }
template <class U = String> static U create_external_cbuf (StdString exp) { return create_external_cbuf<U>(exp, exp.size()); }
static void assign_external (String& s, StdString exp, size_t cap) { s.assign(extstr(exp), exp.size(), cap, &Allocator::ext_free); }
static void assign_external (String& s, StdString exp) { assign_external(s, exp, exp.size()); }
static void assign_external_cbuf (String& s, StdString exp, size_t cap) { s.assign(extstr(exp), exp.size(), cap, &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free); }
static void assign_external_cbuf (String& s, StdString exp) { assign_external_cbuf(s, exp, exp.size()); }
static void test_ctor () {
auto defexp = mstr("this string is definitely longer than max sso chars");
auto defsz = BUF_CHARS + defexp.size();
SECTION("empty") {
{
String s;
REQUIRE_STR(s, EMPTY);
}
CHECK_ALLOCS();
};
SECTION("literal") {
{
String s(LITERAL);
REQUIRE_STR(s, LITERAL, LITERAL_LEN, 0);
}
CHECK_ALLOCS();
};
SECTION("sso") {
StdString cur;
while (cur.size() <= MAX_SSO_CHARS) {
String s(cur.data(), cur.size());
REQUIRE_STR(s, cur, MAX_SSO_CHARS);
if (cur.size() == defexp.size()) throw "should not happen";
cur += defexp[cur.size()];
}
CHECK_ALLOCS();
auto sz = BUF_CHARS + cur.size();
{
String s(cur.data(), cur.size());
REQUIRE_STR(s, cur);
CHECK_ALLOCS(1, sz);
}
CHECK_ALLOCS(0, 0, 1, sz);
}
SECTION("internal with len") {
{
String s(defexp.data(), defexp.size());
REQUIRE_STR(s, defexp);
}
CHECK_ALLOCS(1, defsz, 1, defsz);
}
SECTION("internal without len") {
{
String s(defexp.c_str());
REQUIRE_STR(s, defexp);
}
CHECK_ALLOCS(1, defsz, 1, defsz);
}
SECTION("external") {
{
String s(extstr(defexp), defexp.size(), defexp.size(), &Allocator::ext_free);
REQUIRE_STR(s, defexp);
}
CHECK_ALLOCS(1, EBUF_CHARS, 1, EBUF_CHARS, 0, 0, 1, defexp.size());
}
SECTION("external with custom buf") {
{
String s(extstr(defexp), defexp.size(), defexp.size(), &Allocator::ext_free, shared_buf_alloc(), &Allocator::shared_buf_free);
REQUIRE_STR(s, defexp);
CHECK_ALLOCS();
}
CHECK_ALLOCS(0, 0, 0, 0, 0, 0, 1, defexp.size(), 1);
}
SECTION("fill") {
SECTION("sso") {
{
auto exp = mstr("aa");
String s(exp.size(), (T)'a');
REQUIRE_STR(s, exp, MAX_SSO_CHARS);
}
CHECK_ALLOCS();
};
SECTION("internal") {
auto exp = mstr("B", 50);
{
String s(exp.size(), (T)'B');
t/string_test.h view on Meta::CPAN
CHECK_ALLOCS();
}
CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
}
}
template <class FString>
static void test_copy_ctor_offset () {
SECTION("from literal") {
{
auto exp = StdString(LITERAL).substr(2, 25);
FString src(LITERAL);
String s(src, 2, 25);
REQUIRE_STR(src, LITERAL, LITERAL_LEN, 0);
REQUIRE_STR(s, exp, 0);
}
CHECK_ALLOCS();
}
SECTION("from sso") {
{
auto exp = mstr("bu");
FString src(exp.c_str());
String s(src, 1, 1);
REQUIRE_STR(src, exp, MAX_SSO_CHARS);
REQUIRE_STR(s, mstr("u"), MAX_SSO_CHARS-1);
}
CHECK_ALLOCS();
}
SECTION("from internal") {
auto exp = mstr("bu", 50);
auto sz = BUF_CHARS + exp.size();
{
FString src(exp.c_str());
CHECK_ALLOCS(1, sz);
String s(src, 9, 5);
REQUIRE_STR(src, exp, 0, exp.size());
REQUIRE_STR(s, mstr("ububu"), 0, exp.size()-9);
CHECK_ALLOCS();
}
CHECK_ALLOCS(0,0,1,sz);
}
SECTION("from external") {
auto exp = mstr("c", 50);
{
FString src(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
CHECK_ALLOCS(1, EBUF_CHARS);
String s(src, 10, 30);
REQUIRE_STR(src, exp, 0, exp.size());
REQUIRE_STR(s, mstr("c", 30), 0, exp.size()-10);
CHECK_ALLOCS();
}
CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
}
SECTION("out of bounds") {
auto exp = mstr("hello");
FString src(exp.c_str());
SECTION("too big length acts as npos") {
String s(src, 3, 10);
REQUIRE_STRM(s, mstr("lo"));
}
SECTION("too big offset throws exception") {
REQUIRE_THROWS(String(src, 6, 10));
}
}
}
static void test_substr () {
auto exp = mstr("hello world, hello world!");
String src(exp.c_str());
String s = src.substr(0, 5);
REQUIRE_STR(s, mstr("hello"), 0, exp.size());
s = src.substr(6);
REQUIRE_STR(s, mstr("world, hello world!"), 0, exp.size()-6);
s = src.substr(4, 3);
REQUIRE_STR(s, mstr("o w"), 0, exp.size()-4);
REQUIRE_STR(src, exp, 0, exp.size());
}
static void test_clear () {
SECTION("literal") {
{
String s(LITERAL);
s.clear();
REQUIRE_STR(s, EMPTY);
}
CHECK_ALLOCS();
}
SECTION("sso") {
{
auto exp = mstr("bu");
String s(exp.c_str());
s.clear();
REQUIRE_STR(s, EMPTY, 0, MAX_SSO_CHARS);
}
CHECK_ALLOCS();
}
SECTION("internal") {
auto exp = mstr("bu", 50);
{
String s(exp.c_str());
get_allocs();
s.clear();
REQUIRE_STR(s, EMPTY, 0, exp.size());
}
CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
}
SECTION("external") {
auto exp = mstr("c", 50);
{
String s(extstr(exp), exp.size(), exp.size(), &Allocator::ext_free);
get_allocs();
s.clear();
CHECK_ALLOCS();
REQUIRE_STR(s, EMPTY, 0, exp.size());
}
CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
};
}
struct AssignLiteral { template <size_t U> static void op (String& s, const T (&val)[U]) { s.assign(val); } };
struct OpAssignLiteral { template <size_t U> static void op (String& s, const T (&val)[U]) { s = val; } };
t/string_test.h view on Meta::CPAN
}
SECTION("ptr") {
SECTION("method") { test_assign_ptr<AssignPtr>(); }
SECTION("operator") { test_assign_ptr<OpAssignPtr>(); }
}
SECTION("external") { test_assign_external(); }
SECTION("fill") { test_assign_fill(); }
SECTION("char") { test_assign_char(); }
SECTION("copy") {
SECTION("method") { test_assign_copy<AssignCopy, FString>(); }
SECTION("operator") { test_assign_copy<OpAssignCopy, FString>(); }
}
SECTION("offset") { test_assign_offset<FString>(); }
SECTION("move") {
SECTION("method") { test_assign_move<AssignMove, FString>(); }
SECTION("operator") { test_assign_move<OpAssignMove, FString>(); }
}
}
static void test_offset () {
SECTION("from literal") {
auto exp = StdString(LITERAL).substr(2, 25);
String s(LITERAL);
s.offset(2, 25);
REQUIRE_STR(s, exp, 0);
s = EMPTY;
CHECK_ALLOCS();
}
SECTION("from sso") {
auto exp = mstr("bu");
String s(exp.c_str());
s.offset(1, 1);
REQUIRE_STR(s, mstr("u"), MAX_SSO_CHARS-1);
s = EMPTY;
CHECK_ALLOCS();
}
SECTION("from internal") {
auto exp = mstr("bu", 50);
String s(exp.c_str());
s.offset(9, 5);
REQUIRE_STR(s, mstr("ububu"), 100-9);
s = EMPTY;
auto sz = BUF_CHARS + 100;
CHECK_ALLOCS(1,sz,1,sz);
}
SECTION("from external") {
auto exp = mstr("c", 50);
String s = create_external<>(exp);
s.offset(10, 30);
REQUIRE_STR(s, mstr("c", 30), exp.size()-10);
s = EMPTY;
CHECK_ALLOCS(1, EBUF_CHARS, 1, EBUF_CHARS, 0, 0, 1, exp.size());
}
SECTION("out of bounds") {
auto exp = mstr("hello");
String s(exp.c_str());
SECTION("too big length acts as npos") {
s.offset(3, 10);
REQUIRE_STRM(s, mstr("lo"));
};
SECTION("too big offset throws exception") {
REQUIRE_THROWS(s.offset(6,10));
}
}
}
template <class FString>
static void test_swap () {
SECTION("literal<->literal") {
String s1;
FString s2(LITERAL);
s1.swap(s2);
REQUIRE_STR(s1, LITERAL, LITERAL_LEN, 0);
REQUIRE_STR(s2, EMPTY);
s1 = EMPTY; s2 = EMPTY;
CHECK_ALLOCS();
}
SECTION("literal<->sso") {
auto exp = mstr("eb");
String s1(LITERAL);
FString s2(exp.c_str());
s1.swap(s2);
REQUIRE_STR(s1, exp, MAX_SSO_CHARS);
REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
s1 = EMPTY; s2 = EMPTY;
CHECK_ALLOCS();
}
SECTION("literal<->internal") {
auto exp = mstr("eb", 50);
String s1(LITERAL);
FString s2(exp.c_str());
get_allocs();
s1.swap(s2);
REQUIRE_STR(s1, exp);
REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
s2 = EMPTY;
CHECK_ALLOCS();
s1 = EMPTY;
CHECK_ALLOCS(0,0,1,BUF_CHARS+exp.size());
}
SECTION("literal<->external") {
auto exp = mstr("be", 50);
String s1(LITERAL);
FString s2 = create_external<FString>(exp);
get_allocs();
s1.swap(s2);
REQUIRE_STR(s1, exp);
REQUIRE_STR(s2, LITERAL, LITERAL_LEN, 0);
s2 = EMPTY;
CHECK_ALLOCS();
s1 = EMPTY;
CHECK_ALLOCS(0,0,1,EBUF_CHARS,0,0,1,exp.size());
}
SECTION("sso<->sso") {
auto exp1 = mstr("eb");
auto exp2 = mstr("ta");
String s1(exp1.c_str());
FString s2(exp2.c_str());
s1.swap(s2);
REQUIRE_STR(s1, exp2, MAX_SSO_CHARS);
REQUIRE_STR(s2, exp1, MAX_SSO_CHARS);
( run in 0.516 second using v1.01-cache-2.11-cpan-d7f47b0818f )