libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

nonowning_string.cpp (8135B)


      1 #include "libshit/nonowning_string.hpp"
      2 
      3 #include "libshit/doctest.hpp"
      4 
      5 namespace Libshit
      6 {
      7   using namespace std::string_literals;
      8   TEST_SUITE_BEGIN("Libshit::NonowningString");
      9 
     10   template <typename T>
     11   constexpr static bool IsSV = std::is_same_v<T, StringView>;
     12   template <typename T>
     13   constexpr static bool IsNS = std::is_same_v<T, NonowningString>;
     14 
     15   TEST_CASE_TEMPLATE("NonowningString", T, StringView, NonowningString)
     16   {
     17     static_assert(T::ZERO_TERMINATED == IsNS<T>);
     18 
     19     SUBCASE("construct")
     20     {
     21       T{}; // default
     22       T{nullptr}; // not braindead
     23       T{static_cast<const char*>(nullptr)}; // not capnp level braindead
     24       T{"foo"}; // string literal
     25       char buf[] = "123";
     26       T{buf}; // zero terminated
     27       T{buf, 3};
     28       if constexpr (IsSV<T>) T{buf, 1};
     29       T{buf, buf+3};
     30       T{"abcd"s};
     31     }
     32     SUBCASE("operations")
     33     {
     34       char buf[8] = "foobar";
     35       if (IsSV<T>) buf[6]= 'E';
     36       T t{buf, 6};
     37 
     38       SUBCASE("iterators")
     39       {
     40         CHECK(&*t.begin() == buf);
     41         CHECK(&*t.cbegin() == buf);
     42         CHECK(&*t.end() == buf+6);
     43         CHECK(&*t.cend() == buf+6);
     44         CHECK(*t.rbegin() == 'r');
     45         CHECK(*t.crbegin() == 'r');
     46         CHECK(*--t.rend() == 'f');
     47         CHECK(*--t.crend() == 'f');
     48       }
     49 
     50       SUBCASE("index")
     51       {
     52         CHECK(&t[0] == buf);
     53         CHECK(&t[3] == buf+3);
     54         static_assert(std::is_same_v<decltype(t[0]), const char&>);
     55         CHECK(&t.at(0) == buf);
     56         CHECK(&t.at(4) == buf+4);
     57         CHECK_THROWS(t.at(6));
     58         static_assert(std::is_same_v<decltype(t.at(0)), const char&>);
     59       }
     60 
     61       SUBCASE("access")
     62       {
     63         CHECK(&t.front() == buf);
     64         CHECK(&t.back() == buf+5);
     65         static_assert(std::is_same_v<decltype(t.front()), const char&>);
     66         static_assert(std::is_same_v<decltype(t.back()), const char&>);
     67 
     68         CHECK(t.data() == buf);
     69         static_assert(std::is_same_v<decltype(t.data()), const char*>);
     70         if constexpr (IsNS<T>)
     71         {
     72           CHECK(t.c_str() == buf);
     73           static_assert(std::is_same_v<decltype(t.c_str()), const char*>);
     74         }
     75       }
     76 
     77       SUBCASE("length")
     78       {
     79         CHECK(t.size() == 6); CHECK(t.length() == 6);
     80         CHECK(!t.empty());
     81 
     82         T empty;
     83         CHECK(empty.size() == 0); CHECK(empty.length() == 0);
     84         CHECK(empty.empty());
     85       }
     86 
     87       SUBCASE("remove")
     88       {
     89         T t_pr{t}; t_pr.remove_prefix(2);
     90         CHECK(t_pr == T{buf+2, buf+6});
     91         if constexpr (IsSV<T>)
     92         {
     93           T t_sf{t}; t_sf.remove_suffix(3);
     94           CHECK(t_sf == T{buf, 3});
     95         }
     96 
     97         t.swap(t_pr);
     98         CHECK(t == T{buf+2, buf+6});
     99         CHECK(t_pr == T{buf, buf+6});
    100       }
    101 
    102       SUBCASE("copy")
    103       {
    104         char dst[10] = {'0','1','2','3','4','5','6','7','8','9'};
    105         REQUIRE(t.copy(dst, 4, 1) == 4);
    106         CHECK(StringView{dst, 10} == "ooba456789");
    107         REQUIRE(t.copy(dst, 777, 1) == 5);
    108         CHECK(StringView{dst, 10} == "oobar56789");
    109 
    110         CHECK_THROWS(t.copy(dst, 2, 10));
    111       }
    112 
    113       SUBCASE("substr")
    114       {
    115         auto s = t.substr(1, 3);
    116         CHECK(s == StringView{buf+1, 3});
    117         s = t.substr(1, 99);
    118         CHECK(s == StringView{buf+1, buf+6});
    119       }
    120 
    121       SUBCASE("compare")
    122       {
    123         CHECK(t.compare(t) == 0);
    124         char less[] = "abcx";
    125         StringView sv_less{less};
    126         NonowningString ns_less{less};
    127         CHECK(t.compare(sv_less) > 0);
    128         CHECK(t.compare(ns_less) > 0);
    129         CHECK(ns_less.compare(t) < 0);
    130         CHECK(sv_less.compare(t) < 0);
    131 
    132         CHECK(t.compare(3, 3, t) < 0);
    133         CHECK(t.compare(0, 3, t, 3, 0) > 0);
    134         CHECK(sv_less.compare(3,1, t) > 0);
    135         CHECK(ns_less.compare(3,1, t) > 0);
    136 
    137         // c_str
    138         CHECK(t.compare("foobar") == 0);
    139         CHECK(t.compare("foo") > 0);
    140         CHECK(t.compare(1,3, "oob") == 0);
    141         CHECK(t.compare(0,3, "fooxxx", 3) == 0);
    142       }
    143 
    144       SUBCASE("starts/ends_with")
    145       {
    146         CHECK(t.starts_with(StringView{"foo"}));
    147         CHECK(!t.starts_with(StringView{"fob"}));
    148         CHECK(t.starts_with(NonowningString{"foo"}));
    149         CHECK(!t.starts_with(NonowningString{"fob"}));
    150         CHECK(t.starts_with('f'));
    151         CHECK(!t.starts_with('r'));
    152         CHECK(t.starts_with("foo"));
    153         CHECK(!t.starts_with("fob"));
    154 
    155         CHECK(t.ends_with(StringView{"bar"}));
    156         CHECK(!t.ends_with(StringView{"gar"}));
    157         CHECK(t.ends_with(NonowningString{"bar"}));
    158         CHECK(!t.ends_with(NonowningString{"gar"}));
    159         CHECK(t.ends_with('r'));
    160         CHECK(!t.ends_with('f'));
    161         CHECK(t.ends_with("bar"));
    162         CHECK(!t.ends_with("gar"));
    163       }
    164 
    165       SUBCASE("find")
    166       {
    167         CHECK(t.find("") == 0);
    168         CHECK(t.find(T{"foo"}) == 0);
    169         CHECK(t.find(T{"foo"}, 1) == T::npos);
    170         CHECK(t.find("foo") == 0);
    171         CHECK(t.find("oo") == 1);
    172         CHECK(t.find("oo", 1) == 1);
    173         CHECK(t.find("oo", 2) == T::npos);
    174         CHECK(t.find("o") == 1);
    175         CHECK(t.find("o", 1) == 1);
    176         CHECK(t.find("o", 2) == 2);
    177         CHECK(t.find("o", 3) == T::npos);
    178         CHECK(t.find('o') == 1);
    179         CHECK(t.find('o', 1) == 1);
    180         CHECK(t.find('o', 2) == 2);
    181         CHECK(t.find('o', 3) == T::npos);
    182         CHECK(t.find('r') == 5);
    183         CHECK(t.find("obx", 0, 2) == 2);
    184         CHECK(t.find("foobar") == 0);
    185         CHECK(t.find("bar") == 3);
    186         CHECK(t.substr(0, 3).find("foob") == T::npos);
    187 
    188         CHECK(t.rfind("o") == 2);
    189         CHECK(t.rfind("o", 2) == 2);
    190         CHECK(t.rfind("o", 1) == 1);
    191         CHECK(t.rfind("o", 0) == T::npos);
    192         CHECK(t.rfind('o') == 2);
    193         CHECK(t.rfind('o', 2) == 2);
    194         CHECK(t.rfind('o', 1) == 1);
    195         CHECK(t.rfind('o', 0) == T::npos);
    196         CHECK(t.rfind("foobar") == 0);
    197         CHECK(t.rfind("bar") == 3);
    198         CHECK(t.substr(0, 3).rfind("foob") == T::npos);
    199 
    200         CHECK(t.find_first_of("") == T::npos);
    201         CHECK(t.find_first_of("af") == 0);
    202         CHECK(t.find_first_of("af", 1) == 4);
    203         CHECK(t.find_first_of("af", 5) == T::npos);
    204         CHECK(t.find_first_of("r") == 5);
    205         CHECK(t.find_first_of('r') == 5);
    206         CHECK(t.find_first_of("xyzr") == 5);
    207         CHECK(t.substr(0, 3).find_first_of("b") == T::npos);
    208         CHECK(t.find_last_of("") == T::npos);
    209         CHECK(t.find_last_of('r') == 5);
    210         CHECK(t.find_last_of("r") == 5);
    211         CHECK(t.find_last_of('f') == 0);
    212         CHECK(t.find_last_of("f") == 0);
    213         CHECK(t.find_last_of("af") == 4);
    214         CHECK(t.find_last_of("af", 3) == 0);
    215 
    216         CHECK(t.find_first_not_of('f') == 1);
    217         CHECK(t.find_first_not_of("f") == 1);
    218         CHECK(t.find_first_not_of("of") == 3);
    219         CHECK(t.find_first_not_of("aofrb") == T::npos);
    220         CHECK(t.find_first_not_of("x", 5) == 5);
    221         CHECK(t.find_first_not_of("r", 5) == T::npos);
    222         CHECK(t.find_first_not_of("fbar") == 1);
    223         CHECK(t.find_last_not_of('f') == 5);
    224         CHECK(t.find_last_not_of("f") == 5);
    225         CHECK(t.find_last_not_of('r') == 4);
    226         CHECK(t.find_last_not_of("r") == 4);
    227         CHECK(t.find_last_not_of("ar") == 3);
    228         CHECK(t.find_last_not_of("aofrb") == T::npos);
    229         CHECK(t.find_last_not_of("x", 0) == 0);
    230         CHECK(t.find_last_not_of("f", 0) == T::npos);
    231         CHECK(t.find_last_not_of("fbar") == 2);
    232       }
    233 
    234       SUBCASE("compare")
    235       {
    236         CHECK(t == t); CHECK(!(t != t)); CHECK(!(t < t)); CHECK(!(t > t));
    237         CHECK(t <= t); CHECK(t >= t);
    238 
    239         T t2{"foobar", 6};
    240         CHECK(t == t2); CHECK(!(t != t2)); CHECK(!(t < t2)); CHECK(!(t > t2));
    241         CHECK(t <= t2); CHECK(t >= t2);
    242 
    243         T t3{"abc"};
    244         CHECK(!(t == t3)); CHECK(t != t3); CHECK(!(t < t3)); CHECK(t > t3);
    245         CHECK(!(t <= t3)); CHECK(t >= t3);
    246 
    247         std::string s{"abc"};
    248         CHECK(!(t == s)); CHECK(t != s); CHECK(!(t < s)); CHECK(t > s);
    249         CHECK(!(t <= s)); CHECK(t >= s);
    250       }
    251 
    252       SUBCASE("string plus")
    253       {
    254         std::string str = "abc";
    255         str += t;
    256         CHECK(str == "abcfoobar");
    257       }
    258     }
    259   }
    260 
    261   TEST_SUITE_END();
    262 }