I want to write a very simple std::string like compile-time const char* string.
I need to work with strings in the compiletime, just like with strings, I implemented basic functions.
class cstring final {
const char* str_;
std::size_t size_;
public:
constexpr cstring(const char* str, std::size_t size, std::size_t prefix = 0, std::size_t suffix = 0) noexcept
: str_{str + prefix},
size_{size - prefix - suffix} {}
template <std::size_t N>
constexpr cstring(const char (&str)[N]) noexcept : cstring{str, N - 1, 0, 0} {}
constexpr cstring() noexcept : cstring{nullptr, 0, 0, 0} {}
cstring(const std::string& str) noexcept : cstring{str.data(), str.size(), 0, 0} {}
constexpr cstring(const cstring&) = default;
cstring& operator=(const cstring&) = default;
constexpr std::size_t size() const noexcept { return size_; }
constexpr std::size_t length() const noexcept { return size_; }
constexpr std::size_t max_size() const noexcept {
return (std::numeric_limits<std::size_t>::max)();
}
constexpr bool empty() const noexcept { return size_ == 0; }
constexpr const char* begin() const noexcept { return str_; }
constexpr const char* end() const noexcept { return str_ + size_; }
constexpr const char* cbegin() const noexcept { return begin(); }
constexpr const char* cend() const noexcept { return end(); }
constexpr const char& operator[](std::size_t i) const { return str_[i]; }
constexpr const char& at(std::size_t i) const {
return (i < size_) ? str_[i]
: (throw std::out_of_range{"cstring::at"}, str_[0]);
}
constexpr const char& front() const { return str_[0]; }
constexpr const char& back() const { return str_[size_ - 1]; }
constexpr const char* data() const noexcept { return str_; }
constexpr cstring remove_prefix(std::size_t n) const {
return {str_ + n, size_ - n};
}
constexpr cstring add_prefix(std::size_t n) const {
return {str_ - n, size_ + n};
}
constexpr cstring remove_suffix(std::size_t n) const {
return {str_, size_ - n};
}
constexpr cstring add_suffix(std::size_t n) const {
return {str_, size_ + n};
}
constexpr cstring substr(std::size_t pos, std::size_t n) const {
return {str_ + pos, n};
}
constexpr int compare(cstring other) const {
return (size_ == other.size_) ? detail::StrCompare(str_, other.str_, size_)
: ((size_ > other.size_) ? 1 : -1);
}
friend constexpr bool operator==(cstring lhs, cstring rhs) {
return lhs.compare(rhs) == 0;
}
friend constexpr bool operator!=(cstring lhs, cstring rhs) {
return !(lhs == rhs);
}
std::string append(cstring s) const {
return std::string{str_, size_}.append(s.str_, s.size_);
}
friend std::string operator+(cstring lhs, cstring rhs) {
return std::string{lhs.str_, lhs.size_} + std::string{rhs.str_, rhs.size_};
}
friend std::ostream& operator<<(std::ostream& os, cstring str) {
os.write(str.str_, str.size_);
return os;
}
operator std::string() const { return std::string{str_, size_}; }
};
Note that I use C++11 in my project so I can't use std::string_view
.
string_view
interface, what you want reviewers to focus on, and so on? Also, you want to add missing#include
s forstd::string
andstd::numeric_limits
. A usage example of your class would also be much appreciated. \$\endgroup\$