<commit_before>#ifndef T_BENCH_H
#define T_BENCH_H

#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
#include <chrono>

namespace TBench {
	class Benchmark;
	class Suite;

	/* Timer */

	class Timer {
	private:
		std::chrono::system_clock::time_point _start, _end;

	public:
		typedef long long Time; // ago?

		void start() {
			_start = std::chrono::high_resolution_clock::now();
		}

		void stop() {
			_end = std::chrono::high_resolution_clock::now();
		}

		Time durationInMilliseconds() const {
			auto time = std::chrono::duration_cast<std::chrono::milliseconds>(_end - _start).count();
			return time;
		}
	};

	/* Case */

	class Case {
	public:
		virtual void Register() = 0;
		void operator()();
		virtual ~Case() {}
	};

	inline void Case::operator()() {
		this->Register();
	}

	/* Benchmark */

	class Benchmark {
	public:
		template <typename ... TCases>
		Benchmark(TCases... cases) {
			unpack(cases...);
		}

	private:
		typedef std::vector<std::function<void()>> FuncVector;
		friend class Suite;
		FuncVector _funcs;

		/* Unpacking functions */
		template <typename TCase, typename ... TCases> void unpack(TCase first, TCases... cases);
		template <typename TCase> void unpack(TCase single);
		void unpack() {};

		void run();
	};

	template <typename TCase, typename ... TCases>
	void Benchmark::unpack(TCase first, TCases... cases) {
		_funcs.push_back([=]() mutable { first(); });
		unpack(cases...);
	}

	template <typename TCase>
	void Benchmark::unpack(TCase single) {
		_funcs.push_back([=]() mutable { single(); });
	}

	inline void Benchmark::run() {
		for (auto f : _funcs) f();
	}

	/* Exceptions */

	class BenchmarkException : public std::exception {
	private:
		const std::string _what;

	public:
		explicit BenchmarkException(std::string const& cs)
			: _what(cs) {}

		char const* what() const override {
			return this->_what.c_str();
		}
	};

	/* Suite - Note: This is really not a "true" class. It's just a couple of subroutines, more or less. */

	class Suite {
	private:
		typedef std::unordered_map<std::string, Benchmark> BenchmarkHash;
		static BenchmarkHash _benches;

	public:
		typedef std::function<Timer::Time(std::vector<Timer::Time>)> TimerStrategy;
		template <typename ... TCases>
		static void AddBenchmark(const std::string& name, TimerStrategy strategy, TCases... cases);
		static void Run(const std::string& name);
	};

	Suite::BenchmarkHash Suite::_benches;

	template <typename ... TCases>
	void Suite::AddBenchmark(const std::string& name, TimerStrategy strategy, TCases... cases) {
		_benches.insert(std::make_pair(name, Benchmark(cases...)));
	}

	inline void Suite::Run(std::string const& name) {
		auto bench = _benches.at(name);
		bench.run();
	}
}

#endif<commit_msg>Add a couple of default strategies<commit_after>#ifndef T_BENCH_H
#define T_BENCH_H

#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
#include <chrono>

namespace TBench {
	class Benchmark;
	class Suite;

	/* Timer */

	class Timer {
	private:
		std::chrono::system_clock::time_point _start, _end;

	public:
		typedef long long Time; // ago?

		void start() {
			_start = std::chrono::high_resolution_clock::now();
		}

		void stop() {
			_end = std::chrono::high_resolution_clock::now();
		}

		Time durationInMilliseconds() const {
			auto time = std::chrono::duration_cast<std::chrono::milliseconds>(_end - _start).count();
			return time;
		}
	};

	/* Case */

	class Case {
	public:
		virtual void Register() = 0;
		void operator()();
		virtual ~Case() {}
	};

	inline void Case::operator()() {
		this->Register();
	}

	/* Benchmark */

	class Benchmark {
	public:
		template <typename ... TCases>
		Benchmark(TCases... cases) {
			unpack(cases...);
		}

	private:
		typedef std::vector<std::function<void()>> FuncVector;
		friend class Suite;
		FuncVector _funcs;

		/* Unpacking functions */
		template <typename TCase, typename ... TCases> void unpack(TCase first, TCases... cases);
		template <typename TCase> void unpack(TCase single);
		void unpack() {};

		void run();
	};

	template <typename TCase, typename ... TCases>
	void Benchmark::unpack(TCase first, TCases... cases) {
		_funcs.push_back([=]() mutable { first(); });
		unpack(cases...);
	}

	template <typename TCase>
	void Benchmark::unpack(TCase single) {
		_funcs.push_back([=]() mutable { single(); });
	}

	inline void Benchmark::run() {
		for (auto f : _funcs) f();
	}

	/* Exceptions */

	class BenchmarkException : public std::exception {
	private:
		const std::string _what;

	public:
		explicit BenchmarkException(std::string const& cs)
			: _what(cs) {}

		char const* what() const override {
			return this->_what.c_str();
		}
	};

	/* Suite - Note: This is really not a "true" class. It's just a couple of subroutines, more or less. */

	class Suite {
	private:
		typedef std::unordered_map<std::string, Benchmark> BenchmarkHash;
		static BenchmarkHash _benches;

	public:
		typedef std::function<Timer::Time(std::vector<Timer::Time>)> TimerStrategy;
		template <typename ... TCases>
		static void AddBenchmark(const std::string& name, TimerStrategy strategy, TCases... cases);
		static void Run(const std::string& name);
	};

	Suite::BenchmarkHash Suite::_benches;

	template <typename ... TCases>
	void Suite::AddBenchmark(const std::string& name, TimerStrategy strategy, TCases... cases) {
		_benches.insert(std::make_pair(name, Benchmark(cases...)));
	}

	inline void Suite::Run(std::string const& name) {
		auto bench = _benches.at(name);
		bench.run();
	}

	/* Output calculation functions */

	inline Timer::Time TimeDiff(std::vector<Timer::Time> times) {
		if (times.size() != 2)
			throw BenchmarkException("TimeDiff expects two cases");

		return 0;
		//Timer::Time diff;
	}

	inline Timer::Time TotalTime(std::vector<Timer::Time> times) {
		return 0;
	}
}

#endif
{'fraction_non_alphanumeric': 0.1537542662116041, 'fraction_numerical': 0.0008532423208191126, 'mean_word_length': 4.118777292576419, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 45, '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': '302887', 'n_tokens_mistral': 2213, 'n_tokens_neox': 1944, 'n_words': 497}