#pragma once #include "extract.hpp" #include "function_traits.hpp" #include "restrictions.hpp" #include "type_traits.hpp" #include #include #include namespace ss { INIT_HAS_METHOD(tied); INIT_HAS_METHOD(ss_valid); INIT_HAS_METHOD(error); //////////////// // replace validator //////////////// // replace 'validator' types with elements they operate on // eg. no_validator_tup_t> <=> std::tuple // where ss::nx is a validator '(n)one e(x)cept' which // checks if the returned character is either 'A' or 'B', returns error if not // additionally if one element is left in the pack, it will be unwrapped from // the tuple eg. no_void_validator_tup_t <=> int instead of std::tuple template struct no_validator; template struct no_validator>> { using type = typename member_wrapper::arg_type; }; template struct no_validator { using type = T; }; template using no_validator_t = typename no_validator::type; template struct no_validator_tup { using type = typename apply_trait>::type; }; template struct no_validator_tup> { using type = typename no_validator_tup::type; }; template struct no_validator_tup> { using type = no_validator_t; }; template using no_validator_tup_t = typename no_validator_tup::type; //////////////// // no void tuple //////////////// template struct no_void_tup { using type = typename filter_not>::type; }; template using no_void_tup_t = filter_not_t; //////////////// // no void or validator //////////////// // replace 'validators' and remove void from tuple template struct no_void_validator_tup { using type = no_validator_tup_t>; }; template struct no_void_validator_tup> { using type = no_validator_tup_t>; }; template using no_void_validator_tup_t = typename no_void_validator_tup::type; //////////////// // tied class //////////////// // check if the parameter pack is only one element which is a class and has // the 'tied' method which is to be used for type deduction when converting template struct tied_class { constexpr static bool value = (sizeof...(Ts) == 0 && std::is_class_v && has_m_tied::value); }; template constexpr bool tied_class_v = tied_class::value; // the error can be set inside a string, or a bool enum class error_mode { error_string, error_bool }; //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// 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); } public: static bool match(char c) { return match_impl(c); } constexpr static bool enabled = true; }; template <> class matcher<'\0'> { public: constexpr static bool enabled = false; static bool match(char c) = delete; }; //////////////// // is instance of //////////////// template class Template> struct is_instance_of_char { constexpr static bool value = false; }; template class Template> struct is_instance_of_char, Template> { constexpr static bool value = true; }; /////////////////////////////////////////////////// template struct quote : matcher {}; template struct trim : matcher {}; template struct escape : matcher {}; ///////////////////////////////////////////////// // -> type traits template struct if_then_else; template struct if_then_else { using type = T; }; template struct if_then_else { using type = U; }; ////////////////////////////////////////////// template