#pragma once #include "type_traits.hpp" #include namespace ss { //////////////// // matcher //////////////// 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 inline 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 inline constexpr bool matches_intersect_union() { return matches_intersect() || matches_intersect(); } template <> class matcher<'\0'> { public: constexpr static bool enabled = false; constexpr static std::array matches{'\0'}; static bool match(char c) = delete; }; //////////////// // setup parameters //////////////// template struct quote : matcher {}; template struct trim : matcher {}; template struct trim_left : matcher {}; template struct trim_right : matcher {}; template struct escape : matcher {}; // TODO add limit class multiline; class string_error; //////////////// // setup implementation //////////////// template class Template> struct is_instance_of_matcher : std::false_type {}; template class Template> struct is_instance_of_matcher, Template> : std::true_type {}; template class Template> using is_instance_of_matcher_t = typename is_instance_of_matcher::type; template