<commit_before>#pragma once
#ifndef _cmd_args_h_
#define _cmd_args_h_

#include <cstring>
#include <memory>
#include <sstream>
#include <vector>
#include <type_traits>

using namespace std;

namespace command_line {

	template < class _t >
	inline bool _cast(const char * orig, _t & dest) {
		stringstream stream(orig);

		_t val = _t ();
		stream >> val;

		if (stream) {
			dest = val;
			return true;
		} else {
			return false;
		}
	}

	inline bool _cast(const char * orig, std::string & dest) {
		dest = orig;
		return true;
	}

	// iterator domain range 
	struct _range_t {
		char const * const * it;
		char const * const * end;

		// returns true if range is length is zero
		inline bool finished() const { return it == end; }

		// consume first item in range and return it's value
		inline const char * consume() {
			return *it++;
		}

		inline static _range_t intersect(
			const _range_t & v1,
			const _range_t & v2
			) {
			if (distance(v1.it, v2.it) > 0)
				return{ v1.it, v2.it };
			else
				return{ v2.it, v1.it };
		}

	};

	struct _act_t {
		virtual ~_act_t() {}
	};

	template < class _settings_t >
	struct _typed_act_t : public _act_t {
		virtual void exec(const _range_t & range, _settings_t & settings) const = 0;
	};

	// action for options
	template < class _settings_t >
	struct _option_act_t : public _typed_act_t < _settings_t > {
		using field_t = bool _settings_t::*;
		field_t address;

		_option_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;

			settings.*address = true;
		}
	};

	// setter action specialization for single items
	template < class _settings_t, class _t >
	struct _setter_act_t : public _typed_act_t < _settings_t > {
		using field_t = _t _settings_t::*;
		field_t address;

		_setter_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;
            
            // find '=' key / value separator
            auto * vc = strchr(*range.it, '=') + 1;

			// TODO: evaluate cast result and report
			_cast(vc, settings.*address);
		}
	};

	// setter specialization for vectors
	template < class _settings_t, class _item_t, class ... _other_tv >
	struct _setter_act_t < _settings_t, std::vector < _item_t, _other_tv...> > : public _typed_act_t < _settings_t > {
		using field_t = std::vector < _item_t, _other_tv...> _settings_t::*;
		field_t address;

		_setter_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;

			for (auto it = range.it; it != range.end; ++it) {
				_item_t value = _item_t ();
                
                // find '=' key / value separator
                auto * vc = strchr(*it, '=');

				if (_cast(vc, value)) {
					(settings.*address).push_back(value);
				} else {
					// TODO: should report error
				}
			}
		}
	};<commit_msg>fix vector setter<commit_after>#pragma once
#ifndef _cmd_args_h_
#define _cmd_args_h_

#include <cstring>
#include <memory>
#include <sstream>
#include <vector>
#include <type_traits>

using namespace std;

namespace command_line {

	template < class _t >
	inline bool _cast(const char * orig, _t & dest) {
		stringstream stream(orig);

		_t val = _t ();
		stream >> val;

		if (stream) {
			dest = val;
			return true;
		} else {
			return false;
		}
	}

	inline bool _cast(const char * orig, std::string & dest) {
		dest = orig;
		return true;
	}

	// iterator domain range 
	struct _range_t {
		char const * const * it;
		char const * const * end;

		// returns true if range is length is zero
		inline bool finished() const { return it == end; }

		// consume first item in range and return it's value
		inline const char * consume() {
			return *it++;
		}

		inline static _range_t intersect(
			const _range_t & v1,
			const _range_t & v2
			) {
			if (distance(v1.it, v2.it) > 0)
				return{ v1.it, v2.it };
			else
				return{ v2.it, v1.it };
		}

	};

	struct _act_t {
		virtual ~_act_t() {}
	};

	template < class _settings_t >
	struct _typed_act_t : public _act_t {
		virtual void exec(const _range_t & range, _settings_t & settings) const = 0;
	};

	// action for options
	template < class _settings_t >
	struct _option_act_t : public _typed_act_t < _settings_t > {
		using field_t = bool _settings_t::*;
		field_t address;

		_option_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;

			settings.*address = true;
		}
	};

	// setter action specialization for single items
	template < class _settings_t, class _t >
	struct _setter_act_t : public _typed_act_t < _settings_t > {
		using field_t = _t _settings_t::*;
		field_t address;

		_setter_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;
            
            // find '=' key / value separator
            auto * vc = strchr(*range.it, '=') + 1;

			// TODO: evaluate cast result and report
			_cast(vc, settings.*address);
		}
	};

	// setter specialization for vectors
	template < class _settings_t, class _item_t, class ... _other_tv >
	struct _setter_act_t < _settings_t, std::vector < _item_t, _other_tv...> > : public _typed_act_t < _settings_t > {
		using field_t = std::vector < _item_t, _other_tv...> _settings_t::*;
		field_t address;

		_setter_act_t(field_t address_v) : address(address_v) {}

		virtual void exec(const _range_t & range, _settings_t & settings) const override {
			//(TODO: should raise somekind of error)
			if (range.finished())
				return;

			for (auto it = range.it; it != range.end; ++it) {
				_item_t value = _item_t ();
                
                // find '=' key / value separator
                auto * vc = strchr(*it, '=') + 1;

				if (_cast(vc, value)) {
					(settings.*address).push_back(value);
				} else {
					// TODO: should report error
				}
			}
		}
	};
{'fraction_non_alphanumeric': 0.11721668742216687, 'fraction_numerical': 0.003580323785803238, 'mean_word_length': 2.9489858635525508, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 41, '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': '1258814', 'n_tokens_mistral': 2510, 'n_tokens_neox': 2216, 'n_words': 635}