#include "bstl/string.hpp" #include #include namespace bstl { String::String() : data_("") {} String::String(const std::string& str) : data_(str) {} String::String(const char* str) : data_(str == nullptr ? "" : str) {} std::string String::str() const { return data_; } const char* String::c_str() const { return data_.c_str(); } size_t String::length() const { return data_.length(); } size_t String::size() const { return data_.size(); } bool String::empty() const { return data_.empty(); } char String::at(size_t pos) const { if (pos >= data_.size()) { throw std::out_of_range("String::at: index out of range"); } return data_[pos]; } char String::operator[](size_t pos) const { return data_[pos]; } char& String::operator[](size_t pos) { return data_[pos]; } std::vector String::split(const String& delimiter) const { std::vector result; if (data_.empty()) { return result; } if (delimiter.empty()) { result.push_back(*this); return result; } size_t start = 0; size_t pos = 0; while ((pos = data_.find(delimiter.data_, start)) != std::string::npos) { result.push_back(String(data_.substr(start, pos - start))); start = pos + delimiter.size(); } result.push_back(String(data_.substr(start))); return result; } String String::join(const std::vector& parts, const String& delimiter) { if (parts.empty()) { return String(""); } std::string result = parts[0].str(); for (size_t i = 1; i < parts.size(); i++) { result += delimiter.str() + parts[i].str(); } return String(result); } String String::replace(const String& oldStr, const String& newStr, int count) const { if (oldStr.empty()) { return *this; } std::string result = data_; size_t pos = 0; int replaced = 0; while ((pos = result.find(oldStr.data_, pos)) != std::string::npos && (count < 0 || replaced < count)) { result.replace(pos, oldStr.size(), newStr.str()); pos += newStr.size(); replaced++; } return String(result); } String String::upper() const { std::string result = data_; std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::toupper(c); }); return String(result); } String String::lower() const { std::string result = data_; std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::tolower(c); }); return String(result); } String String::capitalize() const { if (data_.empty()) { return *this; } std::string result = data_; result[0] = std::toupper(static_cast(result[0])); for (size_t i = 1; i < result.size(); i++) { result[i] = std::tolower(static_cast(result[i])); } return String(result); } String String::title() const { std::string result = data_; bool newWord = true; for (size_t i = 0; i < result.size(); i++) { if (std::isspace(static_cast(result[i]))) { newWord = true; } else { if (newWord) { result[i] = std::toupper(static_cast(result[i])); newWord = false; } else { result[i] = std::tolower(static_cast(result[i])); } } } return String(result); } bool String::startswith(const String& prefix) const { if (prefix.size() > data_.size()) { return false; } return data_.compare(0, prefix.size(), prefix.data_) == 0; } bool String::endswith(const String& suffix) const { if (suffix.size() > data_.size()) { return false; } return data_.compare(data_.size() - suffix.size(), suffix.size(), suffix.data_) == 0; } bool String::contains(const String& substring) const { return data_.find(substring.data_) != std::string::npos; } bool String::isdigit() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (!std::isdigit(c)) return false; } return true; } bool String::isalpha() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (!std::isalpha(c)) return false; } return true; } bool String::isalnum() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (!std::isalnum(c)) return false; } return true; } bool String::isspace() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (!std::isspace(c)) return false; } return true; } bool String::isupper() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (std::isalpha(c) && !std::isupper(c)) { return false; } } return true; } bool String::islower() const { if (data_.empty()) return false; for (unsigned char c : data_) { if (std::isalpha(c) && !std::islower(c)) { return false; } } return true; } int String::find(const String& substring, size_t start) const { size_t pos = data_.find(substring.data_, start); return pos == std::string::npos ? -1 : static_cast(pos); } int String::rfind(const String& substring) const { size_t pos = data_.rfind(substring.data_); return pos == std::string::npos ? -1 : static_cast(pos); } int String::count(const String& substring) const { if (substring.empty()) return 0; int count = 0; size_t pos = 0; while ((pos = data_.find(substring.data_, pos)) != std::string::npos) { count++; pos += substring.size(); } return count; } String String::strip() const { size_t start = 0; size_t end = data_.size(); while (start < end && std::isspace(static_cast(data_[start]))) { start++; } while (end > start && std::isspace(static_cast(data_[end - 1]))) { end--; } return String(data_.substr(start, end - start)); } String String::lstrip() const { size_t start = 0; while (start < data_.size() && std::isspace(static_cast(data_[start]))) { start++; } return String(data_.substr(start)); } String String::rstrip() const { size_t end = data_.size(); while (end > 0 && std::isspace(static_cast(data_[end - 1]))) { end--; } return String(data_.substr(0, end)); } String String::strip(const String& chars) const { size_t start = 0; size_t end = data_.size(); while (start < end && chars.data_.find(data_[start]) != std::string::npos) { start++; } while (end > start && chars.data_.find(data_[end - 1]) != std::string::npos) { end--; } return String(data_.substr(start, end - start)); } String String::ljust(size_t width, char fillchar) const { if (data_.size() >= width) { return *this; } std::string result = data_; result.append(width - data_.size(), fillchar); return String(result); } String String::rjust(size_t width, char fillchar) const { if (data_.size() >= width) { return *this; } std::string result(width - data_.size(), fillchar); result.append(data_); return String(result); } String String::center(size_t width, char fillchar) const { if (data_.size() >= width) { return *this; } size_t totalPad = width - data_.size(); size_t leftPad = totalPad / 2; size_t rightPad = totalPad - leftPad; std::string result(leftPad, fillchar); result.append(data_); result.append(rightPad, fillchar); return String(result); } int String::toInt() const { return std::stoi(data_); } long long String::toLongLong() const { return std::stoll(data_); } double String::toDouble() const { return std::stod(data_); } String String::operator+(const String& other) const { return String(data_ + other.data_); } String String::operator+(const char* str) const { return String(data_ + (str == nullptr ? "" : str)); } String& String::operator+=(const String& other) { data_ += other.data_; return *this; } bool String::operator==(const String& other) const { return data_ == other.data_; } bool String::operator!=(const String& other) const { return data_ != other.data_; } bool String::operator<(const String& other) const { return data_ < other.data_; } bool String::operator>(const String& other) const { return data_ > other.data_; } bool String::operator<=(const String& other) const { return data_ <= other.data_; } bool String::operator>=(const String& other) const { return data_ >= other.data_; } } // namespace bstl