Skip to content

Commit

Permalink
make noex::string templated
Browse files Browse the repository at this point in the history
  • Loading branch information
matyalatte committed Nov 28, 2024
1 parent 91c2c33 commit b57b48d
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 145 deletions.
3 changes: 2 additions & 1 deletion include/noex/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ enum ErrorNo : int {
OK = 0,
STR_ALLOCATION_ERROR, // Failed to allocate memory for string.
STR_BOUNDARY_ERROR, // Accessed out-of-bounds with substr or [].
STR_FORMAT_ERROR, // Failed to convert number to string.
STR_FORMAT_ERROR, // Failed to convert a number to string.
VEC_ALLOCATION_ERROR,
VEC_BOUNDARY_ERROR,
UNIMPLEMENTED_ERROR, // Called an unimplemented function.
EXTERNAL_ALLOCATION_ERROR, // User defined allocation errors.
EXTERNAL_BOUDARY_ERROR, // User defined boundary errors.
EXTERNAL_ERROR, // User defined errors.
Expand Down
104 changes: 48 additions & 56 deletions include/noex/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,25 @@ namespace noex {
// It works without any crashes even when it got a memory allocation error.
// But you have to check GetErrorNo() after string allocations
// or it might have an unexpected value (an empty string).
class string {
template <typename charT>
class basic_string {
private:
char* m_str;
charT* m_str;
size_t m_size;
void assign(const char* str, size_t size) noexcept;
void append(const char* str, size_t size) noexcept;
void assign(const charT* str, size_t size) noexcept;
void append(const charT* str, size_t size) noexcept;

public:
string() noexcept : m_str(nullptr), m_size(0) {}
string(const char* str) noexcept; // NOLINT(runtime/explicit)
string(const char* str, size_t size) noexcept;
string(const string& str) noexcept;
string(string&& str) noexcept;
basic_string() noexcept : m_str(nullptr), m_size(0) {}
basic_string(const charT* str) noexcept; // NOLINT(runtime/explicit)
basic_string(const charT* str, size_t size) noexcept;
basic_string(const basic_string& str) noexcept;
basic_string(basic_string&& str) noexcept;

// This allocates null bytes to use them as a buffer.
explicit string(size_t size) noexcept;
explicit basic_string(size_t size) noexcept;

~string() noexcept { clear(); }
~basic_string() noexcept { clear(); }
inline size_t length() const noexcept { return m_size; }
inline size_t size() const noexcept { return m_size; }

Expand All @@ -37,87 +38,78 @@ class string {
}

// Returns an immutable C string. This can't be null.
const char* c_str() const noexcept;
const charT* c_str() const noexcept;

// Returns a pointer to the actual buffer.
inline char* data() const noexcept { return m_str; }
inline charT* data() const noexcept { return m_str; }

void clear() noexcept;

const char& operator[](size_t id) const noexcept;
const charT& operator[](size_t id) const noexcept;

string& operator=(const char* str) noexcept;
string& operator=(const string& str) noexcept;
string& operator=(string&& str) noexcept;
basic_string& operator=(const charT* str) noexcept;
basic_string& operator=(const basic_string& str) noexcept;
basic_string& operator=(basic_string&& str) noexcept;

string& operator+=(const char* str) noexcept;
string& operator+=(const string& str) noexcept;
basic_string& operator+=(const charT* str) noexcept;
basic_string& operator+=(const basic_string& str) noexcept;

string operator+(const char* str) const noexcept;
string operator+(const string& str) const noexcept;
basic_string operator+(const charT* str) const noexcept;
basic_string operator+(const basic_string& str) const noexcept;

// You can append numbers as strings
string operator+(int num) const noexcept;
string operator+(size_t num) const noexcept;
string operator+(uint32_t num) const noexcept;

bool operator==(const char* str) const noexcept;
bool operator==(const string& str) const noexcept;
inline bool operator!=(const char* str) const noexcept {
// Note: wstring does not support operator+ for numbers
basic_string operator+(int num) const noexcept;
basic_string operator+(size_t num) const noexcept;
basic_string operator+(uint32_t num) const noexcept;

bool operator==(const charT* str) const noexcept;
bool operator==(const basic_string& str) const noexcept;
inline bool operator!=(const charT* str) const noexcept {
return !(*this == str);
}
inline bool operator!=(const string& str) const noexcept {
inline bool operator!=(const basic_string& str) const noexcept {
return !(*this == str);
}

inline const char* begin() const noexcept {
inline const charT* begin() const noexcept {
return c_str();
}

inline const char* end() const noexcept {
inline const charT* end() const noexcept {
return c_str() + m_size;
}

static const size_t npos;
size_t find(const char c) const noexcept;
size_t find(const char* str) const noexcept;
inline size_t find(const string& str) const noexcept {
size_t find(const charT c) const noexcept;
size_t find(const charT* str) const noexcept;
inline size_t find(const basic_string& str) const noexcept {
return find(str.c_str());
}

inline void push_back(const char c) noexcept {
inline void push_back(const charT c) noexcept {
this->append(&c, 1);
}

string substr(size_t start, size_t size) const noexcept;
basic_string substr(size_t start, size_t size) const noexcept;
};

string operator+(const char* str1, const string& str2) noexcept;
template <typename charT>
basic_string<charT> operator+(const charT* str1, const basic_string<charT>& str2) noexcept;

inline bool operator==(const char* str1, const string& str2) noexcept {
template <typename charT>
inline bool operator==(const charT* str1, const basic_string<charT>& str2) noexcept {
return str2 == str1;
}

inline bool operator!=(const char* str1, const string& str2) noexcept {
template <typename charT>
inline bool operator!=(const charT* str1, const basic_string<charT>& str2) noexcept {
return str2 != str1;
}

class wstring {
private:
wchar_t* m_str;
size_t m_size;

public:
wstring(const wchar_t* str) noexcept; // NOLINT(runtime/explicit)
~wstring() noexcept { clear(); }
inline size_t length() const noexcept { return m_size; }
inline size_t size() const noexcept { return m_size; }
inline bool empty() const noexcept {
return !m_str || m_size == 0;
}

const wchar_t* c_str() const noexcept;
void clear() noexcept;
};
extern template class basic_string<char>;
extern template class basic_string<wchar_t>;
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;

} // namespace noex
Loading

0 comments on commit b57b48d

Please sign in to comment.