<commit_before>#pragma once
#include "ConfigGroup.h"
#include <istream>    // std::istream
#include <list>       // std::list

// TODO: Doc
class ConfigFile
{
	template<typename T>
	friend class ConfigVariable;

	public:
		bool load(std::istream &is);

		ConfigNode copy_node();

	private:
		ConfigNode m_node;
};


// Foward declarations
extern ConfigFile *g_config;
template<typename T>
class ConfigConstraint;


// TODO: Doc
template<typename T>
class ConfigVariable
{
	private:
		ConfigGroup* m_group;
		std::string m_name;
		T m_def_val;

		std::list<ConfigConstraint<T>*> m_constraints;

		// get_val_by_path gets the value at the given config path
		T get_val_by_path(ConfigNode node, std::string path)
		{
			size_t offset = 0;
			ConfigNode cnode = YAML::Clone(node);
			bool going = true;
			while(going)
			{
				size_t noffset = path.find("/", offset);
				if(noffset == std::string::npos)
				{
					going = false;
					break;
				}
				else
				{
					cnode = cnode[path.substr(offset, noffset - offset)];
					if(!cnode.IsDefined())
					{
						return m_def_val;
					}
				}
				offset = noffset + 1;
			}
			cnode = cnode[path.substr(offset, path.length() - offset)];
			if(!cnode.IsDefined())
			{
				return m_def_val;
			}
			return cnode.as<T>();
		}

		bool rtest_constraints(ConfigNode node)
		{
			T val = get_rval(node);
			for(auto it = m_constraints.begin(); it != m_constraints.end(); ++it)
			{
				if(!(*it)->test(val))
				{
					config_error((*it)->error());
					return false;
				}
			}

			return true;
		}

		bool test_constraints()
		{
			T val = get_val();
			for(auto it = m_constraints.begin(); it != m_constraints.end(); ++it)
			{
				if(!(*it)->test(val))
				{
					config_error((*it)->error());
					return false;
				}
			}

			return true;
		}

		rtest get_rtest()
		{
			using namespace std::placeholders;
			return std::bind(&ConfigVariable::rtest_constraints, this, _1);
		}

		test get_test()
		{
			return std::bind(&ConfigVariable::test_constraints, this);
		}

	public:
		ConfigVariable(const std::string& name, const T& def_val,
		               ConfigGroup* grp = &ConfigGroup::root) :
			m_name(name), m_def_val(def_val), m_group(grp)
		{<commit_msg>Added forgotten "()" to function call.<commit_after>#pragma once
#include "ConfigGroup.h"
#include <istream>    // std::istream
#include <list>       // std::list

// TODO: Doc
class ConfigFile
{
	template<typename T>
	friend class ConfigVariable;

	public:
		bool load(std::istream &is);

		ConfigNode copy_node();

	private:
		ConfigNode m_node;
};


// Foward declarations
extern ConfigFile *g_config;
template<typename T>
class ConfigConstraint;


// TODO: Doc
template<typename T>
class ConfigVariable
{
	private:
		ConfigGroup* m_group;
		std::string m_name;
		T m_def_val;

		std::list<ConfigConstraint<T>*> m_constraints;

		// get_val_by_path gets the value at the given config path
		T get_val_by_path(ConfigNode node, std::string path)
		{
			size_t offset = 0;
			ConfigNode cnode = YAML::Clone(node);
			bool going = true;
			while(going)
			{
				size_t noffset = path.find("/", offset);
				if(noffset == std::string::npos)
				{
					going = false;
					break;
				}
				else
				{
					cnode = cnode[path.substr(offset, noffset - offset)];
					if(!cnode.IsDefined())
					{
						return m_def_val;
					}
				}
				offset = noffset + 1;
			}
			cnode = cnode[path.substr(offset, path.length() - offset)];
			if(!cnode.IsDefined())
			{
				return m_def_val;
			}
			return cnode.as<T>();
		}

		bool rtest_constraints(ConfigNode node)
		{
			T val = get_rval(node);
			for(auto it = m_constraints.begin(); it != m_constraints.end(); ++it)
			{
				if(!(*it)->test(val))
				{
					config_error((*it)->error());
					return false;
				}
			}

			return true;
		}

		bool test_constraints()
		{
			T val = get_val();
			for(auto it = m_constraints.begin(); it != m_constraints.end(); ++it)
			{
				if(!(*it)->test(val))
				{
					config_error((*it)->error());
					return false;
				}
			}

			return true;
		}

		rtest get_rtest()
		{
			using namespace std::placeholders;
			return std::bind(&ConfigVariable::rtest_constraints, this, _1);
		}

		test get_test()
		{
			return std::bind(&ConfigVariable::test_constraints, this);
		}

	public:
		ConfigVariable(const std::string& name, const T& def_val,
		               ConfigGroup* grp = &ConfigGroup::root()) :
			m_name(name), m_def_val(def_val), m_group(grp)
		{
{'fraction_non_alphanumeric': 0.1447220346612649, 'fraction_numerical': 0.0013504388926401081, 'mean_word_length': 3.0510483135824975, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 27, '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': '7291484', 'n_tokens_mistral': 1964, 'n_tokens_neox': 1590, 'n_words': 338}