<commit_before>#pragma once

// Iterator traits (compile time information).

#include <iterator>
#include <type_traits>

namespace duck {
namespace Iterator {
	// Access info
	template <typename It> using GetTraits = std::iterator_traits<It>;
	template <typename It> using GetCategory = typename GetTraits<It>::iterator_category;
	template <typename It> using GetDifferenceType = typename GetTraits<It>::difference_type;
	template <typename It> using GetValueType = typename GetTraits<It>::value_type;
	template <typename It> using GetPointerType = typename GetTraits<It>::pointer;
	template <typename It> using GetReferenceType = typename GetTraits<It>::reference;

	template <typename CategoryTag, typename It>
	using HasCategory = std::is_base_of<CategoryTag, GetCategory<It>>;

	// Enable ifs
	template <typename CategoryTag, typename It, typename ReturnType = void>
	using EnableIfHasCategory =
	    typename std::enable_if<HasCategory<CategoryTag, It>::value, ReturnType>::type;

	/* -------------------------------  Iterator typedef ----------------------------- */

	// SFINAE test if member is defined.
	// [!] Do not apply std::iterator_traits beforehand (will not work on raw T*).
	template <typename It> class HasValueType {
	private:
		template <typename T, typename = typename T::value_type> static constexpr bool test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<It> (int()) };
	};
	template <typename It> class HasDifferenceType {
	private:
		template <typename T, typename = typename T::difference_type> static constexpr bool test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<It> (int()) };
	};
	template <typename It> class HasReferenceType {
	private:
		template <typename T, typename = typename T::reference> static constexpr bool test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<It> (int()) };
	};
	template <typename It> class HasPointerType {
	private:
		template <typename T, typename = typename T::pointer> static constexpr bool test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<It> (int()) };
	};

	/* ------------------------------  Container iterator ---------------------------- */

	// SFINAE Test if it supports std::begin()
	template <typename Container> class ContainerHasStdIterator {
	private:
		template <typename T>
		static constexpr decltype (
		    std::begin (std::declval<typename std::add_lvalue_reference<T>::type> ()), bool())
		test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<Container> (int()) };
	};

	// SFINAE Test if it supports begin() (ADL one)
	template <typename Container> class ContainerHasUserIterator {
	private:
		template <typename T>
		static constexpr decltype (begin (std::declval<typename std::add_lvalue_reference<T>::type> ()),
		                           bool())
		test (int) {
			return true;
		}
		template <typename T> static constexpr bool test (...) { return false; }

	public:
		enum { value = test<Container> (int()) };
	};

	template <typename Container> class ContainerHasIterator {
	public:
		enum {
			value =
			    ContainerHasUserIterator<Container>::value || ContainerHasStdIterator<Container>::value
		};
	};

	// SFINAE Get the container iterator type
	namespace Detail {
		// Container should be a container type, possibly const qualified for const_iterator.
		template <typename Container, bool has_user_iterator, bool has_std_iterator>
		struct GetContainerIterator {};
		template <typename Container, bool has_std_iterator>
		struct GetContainerIterator<Container, true, has_std_iterator> {
			using Type =
			    decltype (begin (std::declval<typename std::add_lvalue_reference<Container>::type> ()));
		};
		template <typename Container> struct GetContainerIterator<Container, false, true> {
			using Type = decltype (
			    std::begin (std::declval<typename std::add_lvalue_reference<Container>::type> ()));
		};
	}
	template <typename Container>
	using GetContainerIteratorType =
	    typename Detail::GetContainerIterator<Container, ContainerHasUserIterator<Container>::value,
	                                          ContainerHasStdIterator<Container>::value>::Type;
}
}
<commit_msg>New style traits started.<commit_after>#pragma once

// Iterator traits (compile time information).

// TODO add an sfinae AccessType { using Type = ... } to checkers
// TODO variadic type getter : test one element after another.

#include <iterator>
#include <type_traits>

namespace duck {
namespace Iterator {
	// Access info
	template <typename It> using GetTraits = std::iterator_traits<It>;
	template <typename It> using GetCategory = typename GetTraits<It>::iterator_category;
	template <typename It> using GetDifferenceType = typename GetTraits<It>::difference_type;
	template <typename It> using GetValueType = typename GetTraits<It>::value_type;
	template <typename It> using GetPointerType = typename GetTraits<It>::pointer;
	template <typename It> using GetReferenceType = typename GetTraits<It>::reference;

	template <typename CategoryTag, typename It>
	using HasCategory = std::is_base_of<CategoryTag, GetCategory<It>>;

	// Enable ifs
	template <typename CategoryTag, typename It, typename ReturnType = void>
	using EnableIfHasCategory =
	    typename std::enable_if<HasCategory<CategoryTag, It>::value, ReturnType>::type;

	/* -------------------------------  Iterator typedef ----------------------------- */

	// SFINAE test if member is defined.
	// [!] Do not apply std::iterator_traits beforehand (will not work on raw T*).
	template <typename It> class HasValueType {
	private:
		template <typename T>
		static auto test (T) -> decltype (std::declval<typename T::value_type> (), std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

		template <typename T, bool has_value_type> struct GetImpl {};
		template <typename T> struct GetImpl<T, true> { using Type = typename T::value_type; };

	public:
		enum { value = decltype (test (std::declval<It> ()))::value };
		using Get = GetImpl<It, value>;
	};
	template <typename It> class HasDifferenceType {
	private:
		template <typename T>
		static auto test (T)
		    -> decltype (std::declval<typename T::difference_type> (), std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

	public:
		enum { value = decltype (test (std::declval<It> ()))::value };
	};
	template <typename It> class HasReferenceType {
	private:
		template <typename T>
		static auto test (T) -> decltype (std::declval<typename T::reference> (), std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

	public:
		enum { value = decltype (test (std::declval<It> ()))::value };
	};
	template <typename It> class HasPointerType {
	private:
		template <typename T>
		static auto test (T) -> decltype (std::declval<typename T::pointer> (), std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

	public:
		enum { value = decltype (test (std::declval<It> ()))::value };
	};

	/* ------------------------------  Container iterator ---------------------------- */

	// SFINAE Test if it supports std::begin()
	template <typename Container> class ContainerHasStdIterator {
	private:
		template <typename T>
		static auto test (T)
		    -> decltype (std::begin (std::declval<typename std::add_lvalue_reference<T>::type> ()),
		                 std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

	public:
		enum { value = decltype (test (std::declval<Container> ()))::value };
	};

	// SFINAE Test if it supports begin() (ADL one)
	template <typename Container> class ContainerHasUserIterator {
	private:
		template <typename T>
		static auto test (T)
		    -> decltype (begin (std::declval<typename std::add_lvalue_reference<T>::type> ()),
		                 std::true_type{});
		static auto test (...) -> decltype (std::false_type{});

	public:
		enum { value = decltype (test (std::declval<Container> ()))::value };
	};

	template <typename Container> class ContainerHasIterator {
	public:
		enum {
			value =
			    ContainerHasUserIterator<Container>::value || ContainerHasStdIterator<Container>::value
		};
	};

	// SFINAE Get the container iterator type
	namespace Detail {
		// Container should be a container type, possibly const qualified for const_iterator.
		template <typename Container, bool has_user_iterator, bool has_std_iterator>
		struct GetContainerIterator {};
		template <typename Container, bool has_std_iterator>
		struct GetContainerIterator<Container, true, has_std_iterator> {
			using Type =
			    decltype (begin (std::declval<typename std::add_lvalue_reference<Container>::type> ()));
		};
		template <typename Container> struct GetContainerIterator<Container, false, true> {
			using Type = decltype (
			    std::begin (std::declval<typename std::add_lvalue_reference<Container>::type> ()));
		};
	}
	template <typename Container>
	using GetContainerIteratorType =
	    typename Detail::GetContainerIterator<Container, ContainerHasUserIterator<Container>::value,
	                                          ContainerHasStdIterator<Container>::value>::Type;
}
}

{'fraction_non_alphanumeric': 0.14730399915585102, 'fraction_numerical': 0.0, 'mean_word_length': 3.8605128205128203, 'pattern_counts': {'":': 0, '<': 133, '<?xml version=': 0, '>': 145, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7282610', 'n_tokens_mistral': 2843, 'n_tokens_neox': 2613, 'n_words': 804}