hmmm

🧩 Syntax:
#pragma once
#include <cstdlib>

class new_string
{
public:

	/* Initial construction can either do nothing, or take a wchar_t* , char* , or a const version of either.
	We can take either a wide or regular char, as we store it in a wchar_t, and can directly convert a char to a wchar.
	
	The only time it matters is when we request a char* from our string object, and need to convert the wide string to
	a regular. */

	new_string() { } 

	template <typename T>
	new_string(T string)
	{
		assign(string);
	}

	/* Copy constructor copies contents of the old string's wchar*, as the old string's wchar* will be freed when it leaves scope */

	/*
	new_string(new_string& constructor_string)
	{
		assign(constructor_string.w_string());
	}
	*/

	void operator= (new_string string)
	{
		assign(string.w_string());
	}

	template <typename T>
	void operator= (T string)
	{
		assign(string);
	}

	void operator+= (new_string additional_string)
	{
		wchar_t* new_string = (wchar_t*)malloc((size + additional_string.size) * sizeof(wchar_t));

		for (int i = 0; i < size; i++)
			new_string[i] = wide_string[i];

		for (int i = 0; i <= additional_string.size; i++)
			new_string[size - 1 + i] = additional_string.wide_string[i];

		wide_string = new_string;

		/* we only kept one of the trailing '\0' from the strings, so new size is size of both strings - 1 */
		size = size + additional_string.size - 1;
	}

	new_string operator+ (new_string additional_string)
	{
		wchar_t* tmp_string = (wchar_t*)malloc((size + additional_string.size) * sizeof(wchar_t));

		for (int i = 0; i < size; i++)
			tmp_string[i] = wide_string[i];

		for (int i = 0; i <= additional_string.size; i++)
			tmp_string[size - 1 + i] = additional_string.wide_string[i];

		new_string new_obj = tmp_string;
		free(tmp_string);
		return new_obj;
	}

	/* free our internal wchar_t* on destruction */
	~ new_string()
	{
		if (wide_string)
			free(wide_string);
	}

	/* getter functions */

	wchar_t* w_string()
	{
		return wide_string;
	}

	size_t get_size()
	{
		/* the size we use internally is that of the full string, but
		the user doesn't care about the terminating '\0' */
		return size - 1;
	}

private:
	int test = 0;

	template <typename T>
	void assign(T string)
	{
		if(wide_string)
			free(wide_string);

		/* Add +2 to the legnth, as we start indexing at zero and our legnth is that of the full string, which
		includes the '\0' */
		for (int i = 0; string[i] != '\0'; i++)
			size = i + 2;

		wide_string = (wchar_t*)malloc(size * sizeof(wchar_t));

		for (int i = 0; i <= size - 1; i++)
			wide_string[i] = string[i];
	}


	wchar_t* wide_string = 0;
	size_t size = 0;

};