diff --git a/include/ss/setup.hpp b/include/ss/setup.hpp new file mode 100644 index 0000000..4474d96 --- /dev/null +++ b/include/ss/setup.hpp @@ -0,0 +1,111 @@ +#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