// Copyright 2022 Jeisson Hidalgo ECCI-UCR CC-BY-4.0 #ifndef STRING_HPP #define STRING_HPP #include #define TESTING #define implicit namespace ecci { class String { private: /// Count of characters stored in text size_t length; /// Pointer to the first char char* text; public: /// Default constructor and conversion constructor implicit String(const char* text = ""); /// Conversion constructor implicit String(char ch); /// Capacity constructor explicit String(const size_t length); /// Copy constructor. Copy semantics String(const String& other); /// Move constructor. Move semantics String(String&& other); /// Destructor ~String(); /// Copy assignment operator. Copy semantics String& operator=(const String& other); /// Move assignment operator. Move semantics String& operator=(String&& other); public: // Accessors /// Get the count of chars inline size_t getLength() const { return this->length; } /// Get access to the internal text inline const char* getText() const { return this->text; } /// Get access to the internal text: std uses c_str() or data() methods inline const char* c_str() const { return this->text; } #ifdef DANGEROUS /// Converts ecci::String object when it is used within a const char* context inline explicit operator const char*() const { return this->text; } #endif /// Get read-only access to the i-th char element. Caller must be sure index /// is not out of bounds inline const char& operator[](size_t index) const { // const String* this return this->text[index]; } /// Get read-write access to the i-th char element. Caller must be sure index /// is not out of bounds inline char& operator[](size_t index) { // String* this return this->text[index]; } /// Get read-only access to the i-th char element. An exception is launched /// if index is out of bounds const char& at(size_t index) const; /// Get read-write access to the i-th char element. An exception is launched /// if index is out of bounds char& at(size_t index); public: // Input/output /// E.g: std::cout << string << std::endl friend std::ostream& operator<<(std::ostream& output, const String& text); /// Read a token from the given stream. E.g: std::cin >> string friend std::istream& operator>>(std::istream& input, String& text); public: /// Concatenation str1 + str2 friend String operator+(const String& left, const String& right); /// Extends this object concatenating the given string /// friend String& operator+=(String& left, const String& right); String& operator+=(const String& right); private: /// This is not a buffered string, capacity is always length + 1 inline size_t capacity() const { return this->length + 1; } #ifdef TESTING private: /// Counts the amount of String instances created during process execution static size_t instanceCount; public: /// Returns the count of instances created during process execution inline static size_t getInstanceCount() { return String::instanceCount; } #endif // TESTING }; } // namespace ecci #endif // STRING_HPP