<commit_before>#ifndef RDESTL_FIXED_SUBSTRING_H
#define RDESTL_FIXED_SUBSTRING_H

#include "rdestl/fixed_array.h"
#include "rdestl/string_utils.h"

namespace rde
{
// "Substring" of fixed size.
// Cannot grow.
// Never allocates memory.
// !! WORK IN PROGRESS
template<typename E, size_t N>
class fixed_substring : private fixed_array<E, N + 1>
{
	typedef fixed_array<E, N + 1>	Base;
public:
	typedef E		value_type;
	typedef int		size_type;

	fixed_substring()
	{
		data()[0] = value_type(0);
	}
	explicit fixed_substring(const value_type* str)
	{
		assign(str);
	}

	using Base::operator[];
	using Base::data;

	void assign(const value_type* str)
	{
		RDE_ASSERT(str != data());
		const size_type len = (size_type)rde::strlen(str);
		const size_type toCopy = len < N ? len : N;
		Sys::MemCpy(data(), str, toCopy * sizeof(value_type));
		data()[toCopy] = value_type(0);
	}
	void append(const value_type* str)
	{
		const size_type strLen = (size_type)rde::strlen(str);
		const size_type ourLen = (size_type)rde::strlen(data());
		size_type toAppend = strLen;
		if (ourLen + toAppend > N)
			toAppend = N - ourLen;
		Sys::MemCpy(data() + ourLen, str, toAppend * sizeof(value_type));
		data()[ourLen + toAppend] = value_type(0);
	}

	bool empty() const
	{
		// @todo: consider caching string len
		return rde::strlen(data()) == 0;
	}
	bool operator==(const fixed_substring& rhs) const
	{
		return rde::strcompare(data(), rhs.data()) == 0;
	}
};

} // rde<commit_msg>Added possibility of copying between different-size strings<commit_after>#ifndef RDESTL_FIXED_SUBSTRING_H
#define RDESTL_FIXED_SUBSTRING_H

#include "rdestl/fixed_array.h"
#include "rdestl/string_utils.h"

namespace rde
{
// "Substring" of fixed size.
// Cannot grow.
// Never allocates memory.
template<typename E, size_t N>
class fixed_substring : private fixed_array<E, N + 1>
{
	typedef fixed_array<E, N + 1>	Base;
public:
	typedef E		value_type;
	typedef int	size_type;

	fixed_substring()
	{
		data()[0] = value_type(0);
	}
	explicit fixed_substring(const value_type* str)
	{
		assign(str);
	}
	template<size_t M>
	fixed_substring(const fixed_substring<E, M>& rhs)
	{
		assign(rhs.data());
	}

	template<size_t M>
	fixed_substring& operator=(const fixed_substring<E, M>& rhs)
	{
		assign(rhs.data());
		return *this;
	}

	using Base::operator[];
	using Base::data;

	void assign(const value_type* str)
	{
		RDE_ASSERT(str != data());
		const size_type len = (size_type)rde::strlen(str);
		const size_type toCopy = len < N ? len : N;
		Sys::MemCpy(data(), str, toCopy * sizeof(value_type));
		data()[toCopy] = value_type(0);
	}
	void assign(const fixed_substring& rhs)
	{
		assign(rhs.data());
	}

	void append(const value_type* str)
	{
		const size_type strLen = (size_type)rde::strlen(str);
		const size_type ourLen = (size_type)rde::strlen(data());
		size_type toAppend = strLen;
		if (ourLen + toAppend > N)
			toAppend = N - ourLen;
		Sys::MemCpy(data() + ourLen, str, toAppend * sizeof(value_type));
		data()[ourLen + toAppend] = value_type(0);
	}
	void append(const fixed_substring& rhs)
	{
		append(rhs.data());
	}

	bool empty() const
	{
		// @todo: consider caching string len
		return rde::strlen(data()) == 0;
	}
	bool operator==(const fixed_substring& rhs) const
	{
		return rde::strcompare(data(), rhs.data()) == 0;
	}
	bool operator!=(const fixed_substring& rhs) const
	{
		return !(*this == rhs);
	}
};

} // rde
{'fraction_non_alphanumeric': 0.14811542991755006, 'fraction_numerical': 0.004711425206124852, 'mean_word_length': 4.559738134206219, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6768214', 'n_tokens_mistral': 1359, 'n_tokens_neox': 1294, 'n_words': 299}