#pragma once #include "type_traits.hpp" #include namespace ss { template struct matcher { private: template static bool match_impl(char c) { if constexpr (sizeof...(Xs) != 0) { return (c == X) || match_impl(c); } return (c == X); } constexpr static bool contains_string_terminator() { for (const auto& match : matches) { if (match == '\0') { return false; } } return true; } public: static bool match(char c) { return match_impl(c); } constexpr static bool enabled = true; constexpr static std::array matches{Cs...}; static_assert(contains_string_terminator(), "string terminator cannot be used as a match character"); }; template constexpr bool matches_intersect() { for (const auto& first_match : FirstMatcher::matches) { for (const auto& second_match : SecondMatcher::matches) { if (first_match != '\0' && first_match == second_match) { return true; } } } return false; } template <> class matcher<'\0'> { public: constexpr static bool enabled = false; constexpr static std::array matches{'\0'}; static bool match(char c) = delete; }; template struct quote : matcher {}; template struct trim : matcher {}; template struct escape : matcher {}; template class Template> struct is_instance_of_matcher { constexpr static bool value = false; }; template class Template> struct is_instance_of_matcher, Template> { constexpr static bool value = true; }; template