<commit_before>#ifndef __FUNCTIONAL_H__
#define __FUNCTIONAL_H__

#include <functional>
#include <map>
#include <tuple>
#include <type_traits>
#include <utility>

#include "fakeconcepts.h"

namespace xp {
	namespace details {

		template<Function F, int Arity>
		struct functor_base {
			typedef typename function_traits<F>::return_type result_type;
		};

		template<Function F>
		struct functor_base < F, 1 > {
			typedef typename function_traits<F>::return_type result_type;
			typedef typename function_traits<F>::argument<0>::type argument_type;
		};

		template<Function F>
		struct functor_base < F, 2 > {
			typedef typename function_traits<F>::return_type result_type;
			typedef typename function_traits<F>::argument<0>::type first_argument_type;
			typedef typename function_traits<F>::argument<1>::type second_argument_type;
		};

		template <typename R, typename... Args>
		std::function<R(Args...)> memoize(std::function<R(Args...)>&& func, std::true_type) {
			// when R is default constructible
			using namespace std;

			map<tuple<Args...>, R> cache;
			return ([=](Args... args) mutable {
				tuple<Args...> t(args...);
				bool inserted;
				map<tuple<Args...>, R>::iterator pos;
				tie(pos, inserted) = cache.insert(make_pair(t, R {}));
				if (inserted) {
					pos->second = func(args...);
				}
				return pos->second;
			});
		}

		template <typename R, typename... Args>
		std::function<R(Args...)> memoize(std::function<R(Args...)>&& func, std::false_type) {
			// when R is not default constructible
			using namespace std;

			map<tuple<Args...>, R> cache;
			return ([=](Args... args) mutable {
				tuple<Args...> t(args...);
				auto found = cache.find(t);
				if (found == cache.end()) {
					tie(found, std::ignore) = cache.emplace(t, func(args...));
				}
				return found->second;
			});
		}
	}

	//memoize
	template <typename R, typename... Args>
	std::function<R(Args...)> memoize(std::function<R(Args...)> func) {
		using namespace std;
		typedef typename integral_constant < bool, is_default_constructible<R>::value
			|| is_trivially_default_constructible<R>::value
			|| is_nothrow_default_constructible<R>::value > ::type is_result_default_constructible_type;
		return details::memoize(std::move(func), is_result_default_constructible_type());
	}

	template<Function Op>
	class dereference_function_t : public details::functor_base < Op, function_traits<Op>::arity > {
		Op op;

	public:
		dereference_function_t(Op op) : op(op) {}

		template<typename P, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const P& x, const P& y) -> decltype(op(*x, *y)) {
			return op(*x, *y);
		}
		template<typename P, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const P& x, const P& y) const -> decltype(op(*x, *y)) {
			return op(*x, *y);
		}

		template<typename P, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const P& x) -> decltype(op(*x)) {
			return op(*x);
		}
		template<typename P, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const P& x) const -> decltype(op(*x)) {
			return op(*x);
		}
	};

	template<Function Op>
	dereference_function_t<Op> dereference(Op op) {
		return dereference_function_t < Op > {op};
	}

	template<Function Op>
	class negation_function_t : public details::functor_base < Op, function_traits<Op>::arity > {
		Op op;

	public:
		negation_function_t(Op op) : op(op) {}

		template<typename T, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const T& x, const T& y) -> decltype(op(x, y)) {
			return !op(x, y);
		}
		template<typename T, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(typename const T& x, const T& y) const -> decltype(op(x, y)) {
			return !op(x, y);
		}

		template<typename T, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const T& x) -> decltype(op(x)) {
			return !op(x);
		}
		template<typename T, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const T& x) const -> decltype(op(x)) {
			return !op(x);
		}
	};

	template<Function Op>
	negation_function_t<Op> negation(Op op) {
		return negation_function_t < Op > {op};
	}

	template<StrictWeakOrdering Compare>
	class between_t {
		typedef typename Compare::first_argument_type argument_type;
		argument_type lo;
		argument_type up;
		Compare cmp;

	public:
		between_t(argument_type&& lower, argument_type&& upper, Compare&& cmp)
			: lo(std::forward<argument_type>(lower))
			, up(std::forward<argument_type>(upper))
			, cmp(cmp) {}

		bool operator()(const argument_type& x) const {
			return !(cmp(x, lo) || cmp(up, x));
		}
	};

	template <typename T>
	between_t<std::less<T>> between(T&& lower, T&& upper) {
		// precondition: lower <= upper
		return between_t<std::less<T>>(std::forward<T>(lower), std::forward<T>(upper), std::less < T > {});
	}

	template <typename T, StrictWeakOrdering Compare>
	between_t<Compare> between(const Compare& cmp, T&& lower, T&& upper) {
		// precondition: !cmp(upper, lower)
		return between_t<Compare>(std::forward(lower), std::forward(upper), cmp);
	}

	// from sgi extensions
	template<typename T>
	struct identity {
		typedef T argument_type;
		typedef T result_type;

		const T& operator()(const T& x) const {
			return x;
		}
	};<commit_msg>Fixes spaces.<commit_after>#ifndef __FUNCTIONAL_H__
#define __FUNCTIONAL_H__

#include <functional>
#include <map>
#include <tuple>
#include <type_traits>
#include <utility>

#include "fakeconcepts.h"

namespace xp {
	namespace details {

		template<Function F, int Arity>
		struct functor_base {
			typedef typename function_traits<F>::return_type result_type;
		};

		template<Function F>
		struct functor_base<F, 1> {
			typedef typename function_traits<F>::return_type result_type;
			typedef typename function_traits<F>::argument<0>::type argument_type;
		};

		template<Function F>
		struct functor_base<F, 2> {
			typedef typename function_traits<F>::return_type result_type;
			typedef typename function_traits<F>::argument<0>::type first_argument_type;
			typedef typename function_traits<F>::argument<1>::type second_argument_type;
		};

		template <typename R, typename... Args>
		std::function<R(Args...)> memoize(std::function<R(Args...)>&& func, std::true_type) {
			// when R is default constructible
			using namespace std;

			map<tuple<Args...>, R> cache;
			return ([=](Args... args) mutable {
				tuple<Args...> t(args...);
				bool inserted;
				map<tuple<Args...>, R>::iterator pos;
				tie(pos, inserted) = cache.insert(make_pair(t, R {}));
				if (inserted) {
					pos->second = func(args...);
				}
				return pos->second;
			});
		}

		template <typename R, typename... Args>
		std::function<R(Args...)> memoize(std::function<R(Args...)>&& func, std::false_type) {
			// when R is not default constructible
			using namespace std;

			map<tuple<Args...>, R> cache;
			return ([=](Args... args) mutable {
				tuple<Args...> t(args...);
				auto found = cache.find(t);
				if (found == cache.end()) {
					tie(found, std::ignore) = cache.emplace(t, func(args...));
				}
				return found->second;
			});
		}
	}

	//memoize
	template <typename R, typename... Args>
	std::function<R(Args...)> memoize(std::function<R(Args...)> func) {
		using namespace std;
		typedef typename integral_constant < bool, is_default_constructible<R>::value
			|| is_trivially_default_constructible<R>::value
			|| is_nothrow_default_constructible<R>::value > ::type is_result_default_constructible_type;
		return details::memoize(std::move(func), is_result_default_constructible_type());
	}

	template<Function Op>
	class dereference_function_t : public details::functor_base < Op, function_traits<Op>::arity > {
		Op op;

	public:
		dereference_function_t(Op op) : op(op) {}

		template<typename P, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const P& x, const P& y) -> decltype(op(*x, *y)) {
			return op(*x, *y);
		}
		template<typename P, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const P& x, const P& y) const -> decltype(op(*x, *y)) {
			return op(*x, *y);
		}

		template<typename P, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const P& x) -> decltype(op(*x)) {
			return op(*x);
		}
		template<typename P, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const P& x) const -> decltype(op(*x)) {
			return op(*x);
		}
	};

	template<Function Op>
	dereference_function_t<Op> dereference(Op op) {
		return dereference_function_t < Op > {op};
	}

	template<Function Op>
	class negation_function_t : public details::functor_base < Op, function_traits<Op>::arity > {
		Op op;

	public:
		negation_function_t(Op op) : op(op) {}

		template<typename T, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(const T& x, const T& y) -> decltype(op(x, y)) {
			return !op(x, y);
		}
		template<typename T, class = std::enable_if<function_traits<Op>::arity == 2>::type>
		auto operator()(typename const T& x, const T& y) const -> decltype(op(x, y)) {
			return !op(x, y);
		}

		template<typename T, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const T& x) -> decltype(op(x)) {
			return !op(x);
		}
		template<typename T, class = std::enable_if<function_traits<Op>::arity == 1>::type>
		auto operator()(const T& x) const -> decltype(op(x)) {
			return !op(x);
		}
	};

	template<Function Op>
	negation_function_t<Op> negation(Op op) {
		return negation_function_t < Op > {op};
	}

	template<StrictWeakOrdering Compare>
	class between_t {
		typedef typename Compare::first_argument_type argument_type;
		argument_type lo;
		argument_type up;
		Compare cmp;

	public:
		between_t(argument_type&& lower, argument_type&& upper, Compare&& cmp)
			: lo(std::forward<argument_type>(lower))
			, up(std::forward<argument_type>(upper))
			, cmp(cmp) {}

		bool operator()(const argument_type& x) const {
			return !(cmp(x, lo) || cmp(up, x));
		}
	};

	template <typename T>
	between_t<std::less<T>> between(T&& lower, T&& upper) {
		// precondition: lower <= upper
		return between_t<std::less<T>>(std::forward<T>(lower), std::forward<T>(upper), std::less<T> {});
	}

	template <typename T, StrictWeakOrdering Compare>
	between_t<Compare> between(const Compare& cmp, T&& lower, T&& upper) {
		// precondition: !cmp(upper, lower)
		return between_t<Compare>(std::forward(lower), std::forward(upper), cmp);
	}

	// from sgi extensions
	template<typename T>
	struct identity {
		typedef T argument_type;
		typedef T result_type;

		const T& operator()(const T& x) const {
			return x;
		}
	};
{'fraction_non_alphanumeric': 0.1671456382682859, 'fraction_numerical': 0.002410308704922592, 'mean_word_length': 4.549382716049383, 'pattern_counts': {'":': 0, '<': 187, '<?xml version=': 0, '>': 207, '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': '3692042', 'n_tokens_mistral': 4223, 'n_tokens_neox': 3692, 'n_words': 846}