Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added new ctors & operators & refactored code & added additional tests for utf8::ustring #2

Merged
merged 3 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include <chrono>

#include <utf8_string.hpp>

int main()
Expand Down
82 changes: 82 additions & 0 deletions tests/utf8_string_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,86 @@ TEST(utf8_string, replace_char_case_3)
ustr.replace_char("مرحبا", 2);

ASSERT_EQ(ustr.get_str(), "прمرحباпgт");
}

// ---------------------------------------------------------------------------------------------------------------------
TEST(utf8_string, ctors)
{
// ----------------------------- const char* PART -----------------------------
const char* c_str{ "привет" };

utf8::ustring ustr_from_c_str{ c_str };
ASSERT_EQ(c_str, ustr_from_c_str.get_c_str());

ustr_from_c_str.replace_char("g", 0);
ASSERT_NE(c_str, ustr_from_c_str.get_c_str());


// ----------------------------- std::string PART -----------------------------
std::string cpp_str{ "пока" };

utf8::ustring ustr_from_cpp_str{ cpp_str };
ASSERT_EQ(cpp_str, ustr_from_cpp_str.get_c_str());

ustr_from_cpp_str.replace_char("h", 0);
ASSERT_NE(cpp_str, ustr_from_cpp_str.get_c_str());


// ----------------------------- std::string_view PART -----------------------------
std::string_view cpp_str_view{ "что" };

utf8::ustring ustr_from_cpp_str_view{ cpp_str_view };
ASSERT_EQ(cpp_str_view, ustr_from_cpp_str_view.get_c_str());

ustr_from_cpp_str_view.replace_char("L", 0);
ASSERT_NE(cpp_str_view, ustr_from_cpp_str_view.get_c_str());


// ----------------------------- move ctor PART -----------------------------
const char* move_data{ "привет мир" };

utf8::ustring ustr_move{ move_data };
auto other_ustr_move{ std::move(ustr_move) };

ASSERT_EQ(other_ustr_move.get_c_str(), move_data);
ASSERT_NE(ustr_move.get_c_str(), move_data);


// ----------------------------- copy ctor PART -----------------------------
const char* copy_data{ "хеллоу ворлд" };

utf8::ustring copy_data_first{ copy_data };
utf8::ustring copy_data_second{ copy_data_first };

ASSERT_EQ(copy_data, copy_data_first.get_c_str());
ASSERT_EQ(copy_data, copy_data_second.get_c_str());
ASSERT_EQ(copy_data_first, copy_data_second);

// TODO: write for other ctors ....
}

// ---------------------------------------------------------------------------------------------------------------------
TEST(utf8_string, operators)
{
// ----------------------------- move operator PART -----------------------------
const char* move_data{ "hello world" };

utf8::ustring ustr_move{ move_data };
utf8::ustring other_ustr_move;
other_ustr_move = std::move(ustr_move);

ASSERT_EQ(other_ustr_move.get_c_str(), move_data);
ASSERT_NE(ustr_move.get_c_str(), move_data);


// ----------------------------- copy operator PART -----------------------------
const char* copy_data{ "хеллоу ворлд" };

utf8::ustring copy_data_first{ copy_data };
utf8::ustring copy_data_second;
copy_data_second = copy_data_first;

ASSERT_EQ(copy_data, copy_data_first.get_c_str());
ASSERT_EQ(copy_data, copy_data_second.get_c_str());
ASSERT_EQ(copy_data_first, copy_data_second);
}
107 changes: 92 additions & 15 deletions utf8-string-lib/utf8_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,88 @@ namespace utf8
std::istream& operator>>(std::istream& is, ustring& ustr)
{
// TODO: .............................................
throw std::runtime_error("operator >> for utf8::ustring not implemented yet !");
}

// -----------------------------------------------------------------------------------------------------------------
constexpr ustring::ustring()
ustring::ustring()
{
Symbols_Info.reserve(100);
String.reserve(100);
}

// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const char* utf8_str)
ustring::ustring(const std::size_t bytes_reserve)
{
Symbols_Info.reserve(100);
String.reserve(100);
Symbols_Info.reserve(bytes_reserve);
String.reserve(bytes_reserve);
}

// TODO: redo this part
std::size_t next_symbol_position{}; // next symbol position in bytes
for (std::size_t i{}; utf8_str[i] != '\0'; ++i)
{
String.push_back(utf8_str[i]);
if (next_symbol_position == i) // if it`s beginning of a symbol
{
std::uint8_t symbol_size{ Get_Size_Of_Symbol(utf8_str[i]) };
Symbols_Info.push_back(SSymbol_Info{ symbol_size, next_symbol_position });
// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const char* default_string) : ustring(100)
{
Copy_With_Metadata_To_Internal_String(default_string);
}

next_symbol_position += symbol_size;
}
// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const char* default_string, const std::size_t bytes_reserve) : ustring(bytes_reserve)
{
Copy_With_Metadata_To_Internal_String(default_string);
}

// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const std::basic_string<char>& default_string) : ustring(default_string.c_str(), default_string.size() * 2)
{ }

// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const std::basic_string_view<char>& default_string) : ustring(default_string.data(), default_string.size() * 2)
{ }

// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(const ustring& other)
{
String = other.String;
Symbols_Info = other.Symbols_Info;
}

// -----------------------------------------------------------------------------------------------------------------
ustring::ustring(ustring&& other) noexcept
{
String = std::move(other.String);
Symbols_Info = std::move(other.Symbols_Info);
}

// -----------------------------------------------------------------------------------------------------------------
ustring& ustring::operator=(const ustring& other)
{
if (this != &other)
{
String = other.String;
Symbols_Info = other.Symbols_Info;
}

return *this;
}

// -----------------------------------------------------------------------------------------------------------------
ustring& ustring::operator=(ustring&& other) noexcept
{
String = std::move(other.String);
Symbols_Info = std::move(other.Symbols_Info);

return *this;
}

// -----------------------------------------------------------------------------------------------------------------
bool ustring::operator==(const ustring& other) const
{
return (String == other.String);
}

// -----------------------------------------------------------------------------------------------------------------
bool ustring::operator!=(const ustring& other) const
{
return (String != other.String);
}

// -----------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -80,6 +134,12 @@ namespace utf8
return String;
}

// -----------------------------------------------------------------------------------------------------------------
const std::basic_string<char>& ustring::get_c_str() const
{
return String;
}

// -----------------------------------------------------------------------------------------------------------------
std::uint8_t ustring::Get_Size_Of_Symbol(std::uint8_t symbol)
{
Expand Down Expand Up @@ -111,4 +171,21 @@ namespace utf8
Symbols_Info[i].Symbol_Offset += new_offset;
}
}

// -----------------------------------------------------------------------------------------------------------------
void ustring::Copy_With_Metadata_To_Internal_String(const char* default_string)
{
std::size_t next_symbol_position{}; // next symbol position in bytes
for (std::size_t i{}; default_string[i] != '\0'; ++i)
{
String.push_back(default_string[i]);
if (next_symbol_position == i) // if it`s beginning of a symbol
{
std::uint8_t symbol_size{ Get_Size_Of_Symbol(default_string[i]) };
Symbols_Info.push_back(SSymbol_Info{ symbol_size, next_symbol_position });

next_symbol_position += symbol_size;
}
}
}
}
27 changes: 25 additions & 2 deletions utf8-string-lib/utf8_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstring>
#include <cstdint>
#include <cstddef>
#include <stdexcept>

#define ONE_BYTE 0b0000'0000 // first bit 0
#define TWO_BYTE 0b1100'0000 // first three bits 110
Expand All @@ -20,15 +21,37 @@ namespace utf8
friend std::istream& operator>>(std::istream& is, ustring& ustr);

public:
constexpr ustring();
explicit ustring(const char* utf8_str);
ustring();
explicit ustring(const std::size_t bytes_reserve);
explicit ustring(const char* default_string);
explicit ustring(const char* default_string, const std::size_t bytes_reserve);
explicit ustring(const std::basic_string<char>& default_string);
explicit ustring(const std::basic_string_view<char>& default_string);

constexpr ~ustring() = default;

explicit ustring(const ustring& other);
explicit ustring(ustring&& other) noexcept;

ustring& operator=(const ustring& other);
ustring& operator=(ustring&& other) noexcept;

bool operator==(const ustring& other) const;
bool operator!=(const ustring& other) const;

// TODO: ...............................................
char& operator[](std::size_t index) = delete;
const char& operator[](std::size_t index) const = delete;

void replace_char(std::basic_string_view<char> new_symbol, std::size_t idx);

std::basic_string<char>& get_str();
[[nodiscard]] const std::basic_string<char>& get_c_str() const;

private:
std::uint8_t Get_Size_Of_Symbol(std::uint8_t symbol);
void Recalculate_Symbols_Offset(std::size_t start_pos, std::ptrdiff_t new_offset);
void Copy_With_Metadata_To_Internal_String(const char* default_string);

private:
struct SSymbol_Info
Expand Down
Loading