// ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//

#include <iostream>
#include <string.h>
#include <chrono>

void TrimRight(char* s) {

	size_t len = strlen(s);

	char* iter = s + len - 1;

	if (*iter != ' ') {
		// Если последний символ не пробел, 
		// то и обрезать нечего
		return;
	}

	while (*iter == ' ' /*&& iter != s*/) {
		// Идти от конца к началу, 
		// пока не кончатся пробелы либо строка
		iter--;
	}
	
	if (iter == s) {
		// Если строка пройдена
		// и полностью состоит из пробелов
		// то результатом будет пустая строка
		*iter = '\0';
	}
	else {
		// Если пройдены все пробелы 
		// и поиск дошел до первого не пробела,
		// то заменить первый пробел на конец строки.
		*(iter + 1) = '\0';
	}
	
}

void TrimRight2(char* s)
{
	char* spc = 0, *p = s;

	while (*p)
		if (*p == ' ')
			for (spc = p; *++p == ' '; );
		else
			++p;

	if (spc && p != s && p[-1] == ' ')* spc = 0;

	//return s;
}

void TrimRight3(char* s) {

	char* space = nullptr;
	char* p = s;

	while (*p) {
		if (*p == ' ') {
			if (space == nullptr) {
				space = p;
			}
			p++;
		}
		else {
			space = nullptr;
			p++;
		}
	}

	if (space != nullptr) {
		*space = '\0';
	}

}

void TrimRight4 (char * s) {
   size_t len = strlen (s);
   char * it = s + len - 1;

   while (it >= s && *it == ' ') {
	  *(it--) = '\0';
   }
}

void TrimRight5(char* s) {

	char* space = nullptr;
	bool spaceFlag = false;
	char* p = s;

	while (*p) {
		if (*p == ' ') {
			space = p;
			spaceFlag = true;
		} else {
			spaceFlag = false;
		}
		p++;
	}

	if (spaceFlag) {
		*space = '\0';
	}
}

std::chrono::duration<double> testTrimRight (char * str) {
	auto start = std::chrono::high_resolution_clock::now();
	TrimRight(str);
	auto finish = std::chrono::high_resolution_clock::now();
   delete str;
	return (finish - start);
}

std::chrono::duration<double> testTrimRight2 (char * str) {
	auto start = std::chrono::high_resolution_clock::now();
	TrimRight2(str);
	auto finish = std::chrono::high_resolution_clock::now();
   delete str;
	return (finish - start);
}

std::chrono::duration<double> testTrimRight3 (char * str) {
	auto start = std::chrono::high_resolution_clock::now();
	TrimRight3(str);
	auto finish = std::chrono::high_resolution_clock::now();
   delete str;
	return (finish - start);
}

std::chrono::duration<double> testTrimRight4 (char * str) {
	auto start = std::chrono::high_resolution_clock::now();
	TrimRight4(str);
	auto finish = std::chrono::high_resolution_clock::now();
   delete str;
	return (finish - start);
}

std::chrono::duration<double> testTrimRight5 (char * str) {
	auto start = std::chrono::high_resolution_clock::now();
	TrimRight5(str);
	auto finish = std::chrono::high_resolution_clock::now();
   delete str;
	return (finish - start);
}

char * createString (size_t len_chars, size_t len_spaces) {
	char * str = (char *) malloc (sizeof (char) * len_spaces);
	memset (str, ' ', len_spaces);
	str[len_spaces - 1] = '\0';
	for (size_t i = 0; i < len_chars; i++) {
		str[i] = 'A' + rand() % ('Z' - 'A');
	}
	return str;
}

char * copyString (char * src, int len) {
	char * dest = (char *) malloc (sizeof (char) * len);
	memcpy (dest, src, sizeof (char) * len);
	return dest;
}

int main()
{
	const size_t len_chars = 1000;
	const size_t len_spaces = 10000000;
	const int PROBES = 100;
	int i = 0;
	char * data;
	std::chrono::duration<double> e0 = std::chrono::seconds { 0 };
	std::chrono::duration<double> e1 = std::chrono::seconds { 0 };
	std::chrono::duration<double> e2 = std::chrono::seconds { 0 };
	std::chrono::duration<double> e3 = std::chrono::seconds { 0 };
	std::chrono::duration<double> e4 = std::chrono::seconds { 0 };

	while (i++ < PROBES) {
		data = createString (len_chars, len_spaces);
		e0 = (e0 + testTrimRight (copyString (data, len_spaces))) / 2.0;
		e1 = (e1 + testTrimRight2 (copyString (data, len_spaces))) / 2.0;
		e2 = (e2 + testTrimRight3 (copyString (data, len_spaces))) / 2.0;
		e3 = (e3 + testTrimRight4 (copyString (data, len_spaces))) / 2.0;
		e4 = (e4 + testTrimRight5 (copyString (data, len_spaces))) / 2.0;
      delete data;
	}
	std::cout << "Elapsed time testTrimRight: " << e0.count() << " s\n";
	std::cout << "Elapsed time testTrimRight2: " << e1.count() << " s\n";
	std::cout << "Elapsed time testTrimRight3: " << e2.count() << " s\n";
	std::cout << "Elapsed time testTrimRight4: " << e3.count() << " s\n";
	std::cout << "Elapsed time testTrimRight5: " << e4.count() << " s\n";
}
