Refactor and improve CTL and other code

This commit is contained in:
Justine Tunney 2024-06-04 05:41:53 -07:00
parent 1d8f37a2f0
commit 9906f299bb
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
25 changed files with 5768 additions and 5350 deletions

View file

@ -9,4 +9,5 @@ AlignTrailingComments: false
AlignEscapedNewlines: DontAlign
AlwaysBreakTemplateDeclarations: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
FixNamespaceComments: true
---

File diff suppressed because it is too large Load diff

View file

@ -6,39 +6,41 @@
#include <__utility/move.h>
#include <__utility/swap.h>
namespace ctl {
template<typename T>
class Optional
class optional
{
public:
using value_type = T;
~Optional() = default;
~optional() = default;
Optional() noexcept : present_(false)
optional() noexcept : present_(false)
{
}
Optional(const T& value) : present_(true), value_(value)
optional(const T& value) : present_(true), value_(value)
{
}
Optional(T&& value) : present_(true), value_(std::move(value))
optional(T&& value) : present_(true), value_(std::move(value))
{
}
Optional(const Optional& other) : present_(other.present_)
optional(const optional& other) : present_(other.present_)
{
if (present_)
new (&value_) T(other.value_);
}
Optional(Optional&& other) noexcept : present_(other.present_)
optional(optional&& other) noexcept : present_(other.present_)
{
if (present_)
value_ = std::move(other.value_);
}
Optional& operator=(const Optional& other)
optional& operator=(const optional& other)
{
if (this != &other) {
present_ = other.present_;
@ -48,7 +50,7 @@ class Optional
return *this;
}
Optional& operator=(Optional&& other) noexcept
optional& operator=(optional&& other) noexcept
{
if (this != &other) {
present_ = other.present_;
@ -104,7 +106,7 @@ class Optional
value_ = T(std::forward<Args>(args)...);
}
void swap(Optional& other) noexcept
void swap(optional& other) noexcept
{
if (present_ && other.present_) {
std::swap(value_, other.value_);
@ -122,4 +124,6 @@ class Optional
T value_;
};
} // namespace ctl
#endif // COSMOPOLITAN_CTL_OPTIONAL_H_

44
ctl/strcat.cc Normal file
View file

@ -0,0 +1,44 @@
// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*-
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8
//
// Copyright 2024 Justine Alexandra Roberts Tunney
//
// Permission to use, copy, modify, and/or distribute this software for
// any purpose with or without fee is hereby granted, provided that the
// above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "string.h"
#include <stdckdint.h>
#include <string.h>
namespace ctl {
string
strcat(const string_view lhs, const string_view rhs) noexcept
{
string res;
size_t need;
if (ckd_add(&need, lhs.n, rhs.n))
__builtin_trap();
if (ckd_add(&need, need, 1))
__builtin_trap();
res.reserve(need);
if (lhs.n)
memcpy(res.p, lhs.p, lhs.n);
if (rhs.n)
memcpy(res.p + lhs.n, rhs.p, rhs.n);
res.p[res.n = lhs.n + rhs.n] = 0;
return res;
}
} // namespace ctl

43
ctl/strcmp.cc Normal file
View file

@ -0,0 +1,43 @@
// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*-
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8
//
// Copyright 2024 Justine Alexandra Roberts Tunney
//
// Permission to use, copy, modify, and/or distribute this software for
// any purpose with or without fee is hereby granted, provided that the
// above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "string_view.h"
#include <string.h>
namespace ctl {
int
strcmp(const string_view lhs, const string_view rhs) noexcept
{
int r;
size_t m = lhs.n;
if ((m = rhs.n < m ? rhs.n : m)) {
if (!m)
return 0;
if ((r = memcmp(lhs.p, rhs.p, m)))
return r;
}
if (lhs.n == rhs.n)
return 0;
if (m < lhs.n)
return +1;
return -1;
}
} // namespace ctl

View file

@ -21,7 +21,9 @@
#include <__atomic/fence.h>
#include <stdckdint.h>
String::~String() noexcept
namespace ctl {
string::~string() noexcept
{
if (n) {
if (n >= c)
@ -34,33 +36,33 @@ String::~String() noexcept
free(p);
}
String::String(const char* s) noexcept
string::string(const char* s) noexcept
{
append(s, strlen(s));
}
String::String(const String& s) noexcept
string::string(const string& s) noexcept
{
append(s.p, s.n);
}
String::String(const StringView s) noexcept
string::string(const string_view s) noexcept
{
append(s.p, s.n);
}
String::String(size_t size, char ch) noexcept
string::string(size_t size, char ch) noexcept
{
resize(size, ch);
}
String::String(const char* s, size_t size) noexcept
string::string(const char* s, size_t size) noexcept
{
append(s, size);
}
const char*
String::c_str() const noexcept
string::c_str() const noexcept
{
if (!n)
return "";
@ -72,7 +74,7 @@ String::c_str() const noexcept
}
void
String::reserve(size_t c2) noexcept
string::reserve(size_t c2) noexcept
{
char* p2;
if (c2 < n)
@ -88,7 +90,7 @@ String::reserve(size_t c2) noexcept
}
void
String::resize(size_t n2, char ch) noexcept
string::resize(size_t n2, char ch) noexcept
{
size_t c2;
if (ckd_add(&c2, n2, 1))
@ -100,7 +102,7 @@ String::resize(size_t n2, char ch) noexcept
}
void
String::append(char ch) noexcept
string::append(char ch) noexcept
{
if (n + 2 > c) {
size_t c2 = c + 2;
@ -112,7 +114,7 @@ String::append(char ch) noexcept
}
void
String::grow(size_t size) noexcept
string::grow(size_t size) noexcept
{
size_t need;
if (ckd_add(&need, n, size))
@ -133,7 +135,7 @@ String::grow(size_t size) noexcept
}
void
String::append(char ch, size_t size) noexcept
string::append(char ch, size_t size) noexcept
{
grow(size);
if (size)
@ -142,7 +144,7 @@ String::append(char ch, size_t size) noexcept
}
void
String::append(const void* data, size_t size) noexcept
string::append(const void* data, size_t size) noexcept
{
grow(size);
if (size)
@ -151,76 +153,54 @@ String::append(const void* data, size_t size) noexcept
}
void
String::pop_back() noexcept
string::pop_back() noexcept
{
if (!n)
__builtin_trap();
p[--n] = 0;
}
String&
String::operator=(String&& s) noexcept
string&
string::operator=(string&& s) noexcept
{
if (p != s.p) {
free(p);
p = s.p;
n = s.n;
c = s.c;
s.p = nullptr;
s.n = 0;
s.c = 0;
if (p) {
clear();
append(s.p, s.n);
} else {
p = s.p;
n = s.n;
c = s.c;
s.p = nullptr;
s.n = 0;
s.c = 0;
}
}
return *this;
}
static String
StrCat(const StringView lhs, const StringView rhs) noexcept
{
String res;
size_t need;
if (ckd_add(&need, lhs.n, rhs.n))
__builtin_trap();
if (ckd_add(&need, need, 1))
__builtin_trap();
res.reserve(need);
if (lhs.n)
memcpy(res.p, lhs.p, lhs.n);
if (rhs.n)
memcpy(res.p + lhs.n, rhs.p, rhs.n);
res.p[res.n = lhs.n + rhs.n] = 0;
return res;
}
String
StringView::operator+(const StringView s) const noexcept
{
return StrCat(*this, s);
}
String
String::operator+(const StringView s) const noexcept
{
return StrCat(*this, s);
}
bool
String::operator==(const StringView s) const noexcept
string::operator==(const string_view s) const noexcept
{
if (n != s.n)
return false;
if (!n)
return true;
return !memcmp(p, s.p, n);
}
bool
String::operator!=(const StringView s) const noexcept
string::operator!=(const string_view s) const noexcept
{
if (n != s.n)
return true;
if (!n)
return false;
return !!memcmp(p, s.p, n);
}
bool
String::contains(const StringView s) const noexcept
string::contains(const string_view s) const noexcept
{
if (!s.n)
return true;
@ -228,44 +208,27 @@ String::contains(const StringView s) const noexcept
}
bool
String::ends_with(const StringView s) const noexcept
string::ends_with(const string_view s) const noexcept
{
if (n < s.n)
return false;
if (!s.n)
return true;
return !memcmp(p + n - s.n, s.p, s.n);
}
bool
String::starts_with(const StringView s) const noexcept
string::starts_with(const string_view s) const noexcept
{
if (n < s.n)
return false;
if (!s.n)
return true;
return !memcmp(p, s.p, s.n);
}
static int
StrCmp(const StringView lhs, const StringView rhs) noexcept
{
int r;
size_t m = lhs.n;
if ((m = rhs.n < m ? rhs.n : m))
if ((r = memcmp(lhs.p, rhs.p, m)))
return r;
if (lhs.n == rhs.n)
return 0;
if (m < lhs.n)
return +1;
return -1;
}
int
String::compare(const StringView s) const noexcept
{
return StrCmp(*this, s);
}
size_t
String::find(char ch, size_t pos) const noexcept
string::find(char ch, size_t pos) const noexcept
{
char* q;
if ((q = (char*)memchr(p, ch, n)))
@ -274,7 +237,7 @@ String::find(char ch, size_t pos) const noexcept
}
size_t
String::find(const StringView s, size_t pos) const noexcept
string::find(const string_view s, size_t pos) const noexcept
{
char* q;
if (pos > n)
@ -284,8 +247,8 @@ String::find(const StringView s, size_t pos) const noexcept
return npos;
}
String
String::substr(size_t pos, size_t count) const noexcept
string
string::substr(size_t pos, size_t count) const noexcept
{
size_t last;
if (pos > n)
@ -296,11 +259,11 @@ String::substr(size_t pos, size_t count) const noexcept
last = n;
if (last > n)
__builtin_trap();
return String(p + pos, count);
return string(p + pos, count);
}
String&
String::replace(size_t pos, size_t count, const StringView& s) noexcept
string&
string::replace(size_t pos, size_t count, const string_view& s) noexcept
{
size_t last;
if (ckd_add(&last, pos, count))
@ -324,49 +287,8 @@ String::replace(size_t pos, size_t count, const StringView& s) noexcept
return *this;
}
int
StringView::compare(const StringView s) const noexcept
{
return StrCmp(*this, s);
}
size_t
StringView::find(char ch, size_t pos) const noexcept
{
char* q;
if (n && (q = (char*)memchr(p, ch, n)))
return q - p;
return npos;
}
size_t
StringView::find(const StringView s, size_t pos) const noexcept
{
char* q;
if (pos > n)
__builtin_trap();
if ((q = (char*)memmem(p + pos, n - pos, s.p, s.n)))
return q - p;
return npos;
}
StringView
StringView::substr(size_t pos, size_t count) const noexcept
{
size_t last;
if (pos > n)
__builtin_trap();
if (count > n - pos)
count = n - pos;
if (ckd_add(&last, pos, count))
last = n;
if (last > n)
__builtin_trap();
return StringView(p + pos, count);
}
String&
String::insert(size_t i, const StringView s) noexcept
string&
string::insert(size_t i, const string_view s) noexcept
{
if (i > n)
__builtin_trap();
@ -384,8 +306,8 @@ String::insert(size_t i, const StringView s) noexcept
return *this;
}
String&
String::erase(size_t pos, size_t count) noexcept
string&
string::erase(size_t pos, size_t count) noexcept
{
if (pos > n)
__builtin_trap();
@ -398,42 +320,4 @@ String::erase(size_t pos, size_t count) noexcept
return *this;
}
bool
StringView::operator==(const StringView s) const noexcept
{
if (n == s.n)
return true;
return !memcmp(p, s.p, n);
}
bool
StringView::operator!=(const StringView s) const noexcept
{
if (n != s.n)
return true;
return !!memcmp(p, s.p, n);
}
bool
StringView::contains(const StringView s) const noexcept
{
if (!s.n)
return true;
return !!memmem(p, n, s.p, s.n);
}
bool
StringView::ends_with(const StringView s) const noexcept
{
if (n < s.n)
return false;
return !memcmp(p + n - s.n, s.p, s.n);
}
bool
StringView::starts_with(const StringView s) const noexcept
{
if (n < s.n)
return false;
return !memcmp(p, s.p, s.n);
}
} // namespace ctl

View file

@ -2,111 +2,16 @@
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_STRING_H_
#define COSMOPOLITAN_CTL_STRING_H_
#include "string_view.h"
struct String;
namespace ctl {
struct StringView
{
const char* p;
size_t n;
struct string;
static constexpr size_t npos = -1;
string
strcat(const string_view, const string_view) noexcept __wur;
constexpr StringView(const char* s) noexcept
: p(s), n(s ? __builtin_strlen(s) : 0)
{
}
constexpr StringView(const char* s, size_t n) noexcept : p(s), n(n)
{
}
inline constexpr ~StringView() noexcept
{
}
int compare(const StringView) const noexcept;
bool operator==(const StringView) const noexcept;
bool operator!=(const StringView) const noexcept;
bool contains(const StringView) const noexcept;
String operator+(const StringView) const noexcept;
bool ends_with(const StringView) const noexcept;
bool starts_with(const StringView) const noexcept;
StringView substr(size_t = 0, size_t = npos) const noexcept;
size_t find(char, size_t = 0) const noexcept;
size_t find(const StringView, size_t = 0) const noexcept;
constexpr StringView& operator=(const StringView& s) noexcept
{
p = s.p;
n = s.n;
return *this;
}
constexpr bool empty() const noexcept
{
return !n;
}
constexpr const char* data() const noexcept
{
return p;
}
constexpr size_t size() const noexcept
{
return n;
}
constexpr size_t length() const noexcept
{
return n;
}
constexpr const char& operator[](size_t i) const noexcept
{
if (i >= n)
__builtin_trap();
return p[i];
}
constexpr void remove_prefix(size_t count)
{
if (count > n)
__builtin_trap();
p += count;
n -= count;
}
constexpr void remove_suffix(size_t count)
{
if (count > n)
__builtin_trap();
n -= count;
}
bool operator<(const StringView& s) const noexcept
{
return compare(s) < 0;
}
bool operator<=(const StringView& s) const noexcept
{
return compare(s) <= 0;
}
bool operator>(const StringView& s) const noexcept
{
return compare(s) > 0;
}
bool operator>=(const StringView& s) const noexcept
{
return compare(s) >= 0;
}
};
struct String
struct string
{
char* p = nullptr;
size_t n = 0;
@ -116,14 +21,14 @@ struct String
using const_iterator = const char*;
static constexpr size_t npos = -1;
~String() noexcept;
String() = default;
String(const StringView) noexcept;
String(const char*) noexcept;
String(const String&) noexcept;
String(const char*, size_t) noexcept;
explicit String(size_t, char = 0) noexcept;
String& operator=(String&&) noexcept;
~string() noexcept;
string() = default;
string(const string_view) noexcept;
string(const char*) noexcept;
string(const string&) noexcept;
string(const char*, size_t) noexcept;
explicit string(size_t, char = 0) noexcept;
string& operator=(string&&) noexcept;
const char* c_str() const noexcept;
void pop_back() noexcept;
@ -134,21 +39,19 @@ struct String
void append(char, size_t) noexcept;
void append(unsigned long) noexcept;
void append(const void*, size_t) noexcept;
String& insert(size_t, const StringView) noexcept;
String& erase(size_t = 0, size_t = npos) noexcept;
String operator+(const StringView) const noexcept;
String substr(size_t = 0, size_t = npos) const noexcept;
String& replace(size_t, size_t, const StringView&) noexcept;
bool operator==(const StringView) const noexcept;
bool operator!=(const StringView) const noexcept;
bool contains(const StringView) const noexcept;
bool ends_with(const StringView) const noexcept;
bool starts_with(const StringView) const noexcept;
int compare(const StringView) const noexcept;
string& insert(size_t, const string_view) noexcept;
string& erase(size_t = 0, size_t = npos) noexcept;
string substr(size_t = 0, size_t = npos) const noexcept;
string& replace(size_t, size_t, const string_view&) noexcept;
bool operator==(const string_view) const noexcept;
bool operator!=(const string_view) const noexcept;
bool contains(const string_view) const noexcept;
bool ends_with(const string_view) const noexcept;
bool starts_with(const string_view) const noexcept;
size_t find(char, size_t = 0) const noexcept;
size_t find(const StringView, size_t = 0) const noexcept;
size_t find(const string_view, size_t = 0) const noexcept;
String(String&& s) noexcept : p(s.p), n(s.n), c(s.c)
string(string&& s) noexcept : p(s.p), n(s.n), c(s.c)
{
s.p = nullptr;
s.n = 0;
@ -252,69 +155,82 @@ struct String
append(ch);
}
void append(const StringView s) noexcept
void append(const string_view s) noexcept
{
append(s.p, s.n);
}
inline constexpr operator StringView() const noexcept
inline constexpr operator string_view() const noexcept
{
return StringView(p, n);
return string_view(p, n);
}
String& operator=(const char* s) noexcept
string& operator=(const char* s) noexcept
{
clear();
append(s);
return *this;
}
String& operator=(const StringView s) noexcept
string& operator=(const string_view s) noexcept
{
clear();
append(s);
return *this;
}
String& operator+=(char x) noexcept
string& operator+=(char x) noexcept
{
append(x);
return *this;
}
String& operator+=(const StringView s) noexcept
string& operator+=(const string_view s) noexcept
{
append(s);
return *this;
}
bool operator<(const StringView s) const noexcept
string operator+(const string_view s) const noexcept
{
return strcat(*this, s);
}
int compare(const string_view s) const noexcept
{
return strcmp(*this, s);
}
bool operator<(const string_view s) const noexcept
{
return compare(s) < 0;
}
bool operator<=(const StringView s) const noexcept
bool operator<=(const string_view s) const noexcept
{
return compare(s) <= 0;
}
bool operator>(const StringView s) const noexcept
bool operator>(const string_view s) const noexcept
{
return compare(s) > 0;
}
bool operator>=(const StringView s) const noexcept
bool operator>=(const string_view s) const noexcept
{
return compare(s) >= 0;
}
};
#pragma GCC diagnostic ignored "-Wliteral-suffix"
} // namespace ctl
inline String
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wliteral-suffix"
inline ctl::string
operator"" s(const char* s, size_t n)
{
return String(s, n);
return ctl::string(s, n);
}
#pragma GCC diagnostic pop
#endif // COSMOPOLITAN_CTL_STRING_H_

111
ctl/string_view.cc Normal file
View file

@ -0,0 +1,111 @@
// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*-
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8
//
// Copyright 2024 Justine Alexandra Roberts Tunney
//
// Permission to use, copy, modify, and/or distribute this software for
// any purpose with or without fee is hereby granted, provided that the
// above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "string_view.h"
#include <stdckdint.h>
#include <string.h>
#include "string.h"
namespace ctl {
size_t
string_view::find(char ch, size_t pos) const noexcept
{
char* q;
if (n && (q = (char*)memchr(p, ch, n)))
return q - p;
return npos;
}
size_t
string_view::find(const string_view s, size_t pos) const noexcept
{
char* q;
if (pos > n)
__builtin_trap();
if ((q = (char*)memmem(p + pos, n - pos, s.p, s.n)))
return q - p;
return npos;
}
string_view
string_view::substr(size_t pos, size_t count) const noexcept
{
size_t last;
if (pos > n)
__builtin_trap();
if (count > n - pos)
count = n - pos;
if (ckd_add(&last, pos, count))
last = n;
if (last > n)
__builtin_trap();
return string_view(p + pos, count);
}
bool
string_view::operator==(const string_view s) const noexcept
{
if (n != s.n)
return false;
if (!n)
return true;
return !memcmp(p, s.p, n);
}
bool
string_view::operator!=(const string_view s) const noexcept
{
if (n != s.n)
return true;
if (!n)
return false;
return !!memcmp(p, s.p, n);
}
bool
string_view::contains(const string_view s) const noexcept
{
if (!s.n)
return true;
return !!memmem(p, n, s.p, s.n);
}
bool
string_view::ends_with(const string_view s) const noexcept
{
if (n < s.n)
return false;
if (!s.n)
return true;
return !memcmp(p + n - s.n, s.p, s.n);
}
bool
string_view::starts_with(const string_view s) const noexcept
{
if (n < s.n)
return false;
if (!s.n)
return true;
return !memcmp(p, s.p, s.n);
}
} // namespace ctl

159
ctl/string_view.h Normal file
View file

@ -0,0 +1,159 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_
#define COSMOPOLITAN_CTL_STRINGVIEW_H_
namespace ctl {
struct string_view;
int
strcmp(const string_view, const string_view) noexcept;
struct string_view
{
const char* p;
size_t n;
using iterator = const char*;
using const_iterator = const char*;
static constexpr size_t npos = -1;
constexpr string_view() noexcept : p(nullptr), n(0)
{
}
constexpr string_view(const char* s) noexcept
: p(s), n(s ? __builtin_strlen(s) : 0)
{
}
constexpr string_view(const char* s, size_t n) noexcept : p(s), n(n)
{
}
inline constexpr ~string_view() noexcept
{
}
bool operator==(const string_view) const noexcept;
bool operator!=(const string_view) const noexcept;
bool contains(const string_view) const noexcept;
bool ends_with(const string_view) const noexcept;
bool starts_with(const string_view) const noexcept;
string_view substr(size_t = 0, size_t = npos) const noexcept;
size_t find(char, size_t = 0) const noexcept;
size_t find(const string_view, size_t = 0) const noexcept;
constexpr string_view& operator=(const string_view& s) noexcept
{
p = s.p;
n = s.n;
return *this;
}
constexpr bool empty() const noexcept
{
return !n;
}
constexpr const char* data() const noexcept
{
return p;
}
constexpr size_t size() const noexcept
{
return n;
}
constexpr size_t length() const noexcept
{
return n;
}
constexpr const char& operator[](size_t i) const noexcept
{
if (i >= n)
__builtin_trap();
return p[i];
}
constexpr void remove_prefix(size_t count)
{
if (count > n)
__builtin_trap();
p += count;
n -= count;
}
constexpr void remove_suffix(size_t count)
{
if (count > n)
__builtin_trap();
n -= count;
}
constexpr const char& front() const
{
if (!n)
__builtin_trap();
return p[0];
}
constexpr const char& back() const
{
if (!n)
__builtin_trap();
return p[n - 1];
}
constexpr const_iterator begin() noexcept
{
return p;
}
constexpr const_iterator end() noexcept
{
return p + n;
}
constexpr const_iterator cbegin() const noexcept
{
return p;
}
constexpr const_iterator cend() const noexcept
{
return p + n;
}
int compare(const string_view s) const noexcept
{
return strcmp(*this, s);
}
bool operator<(const string_view& s) const noexcept
{
return compare(s) < 0;
}
bool operator<=(const string_view& s) const noexcept
{
return compare(s) <= 0;
}
bool operator>(const string_view& s) const noexcept
{
return compare(s) > 0;
}
bool operator>=(const string_view& s) const noexcept
{
return compare(s) >= 0;
}
};
} // namespace ctl
#endif // COSMOPOLITAN_CTL_STRINGVIEW_H_

View file

@ -6,8 +6,10 @@
#include <__utility/move.h>
#include <__utility/swap.h>
namespace ctl {
template<typename T>
struct Vector
struct vector
{
size_t n = 0;
size_t c = 0;
@ -16,14 +18,14 @@ struct Vector
using iterator = T*;
using const_iterator = const T*;
Vector() = default;
vector() = default;
~Vector()
~vector()
{
delete[] p;
}
Vector(const Vector& other)
vector(const vector& other)
{
n = other.n;
c = other.c;
@ -32,7 +34,7 @@ struct Vector
new (&p[i]) T(other.p[i]);
}
Vector(Vector&& other) noexcept
vector(vector&& other) noexcept
{
n = other.n;
c = other.c;
@ -42,7 +44,7 @@ struct Vector
other.p = nullptr;
}
explicit Vector(size_t count, const T& value = T())
explicit vector(size_t count, const T& value = T())
{
n = count;
c = count;
@ -51,7 +53,7 @@ struct Vector
new (&p[i]) T(value);
}
Vector& operator=(const Vector& other)
vector& operator=(const vector& other)
{
if (this != &other) {
T* newData = new T[other.c];
@ -66,7 +68,7 @@ struct Vector
return *this;
}
Vector& operator=(Vector&& other) noexcept
vector& operator=(vector&& other) noexcept
{
if (this != &other) {
delete[] p;
@ -231,7 +233,7 @@ struct Vector
n = n2;
}
void swap(Vector& other) noexcept
void swap(vector& other) noexcept
{
std::swap(n, other.n);
std::swap(c, other.c);
@ -239,4 +241,6 @@ struct Vector
}
};
} // namespace ctl
#endif // COSMOPOLITAN_CTL_OPTIONAL_H_