mirror of
				https://github.com/red0124/ssp.git
				synced 2025-10-31 21:26:45 +01:00 
			
		
		
		
	move setup to seperate header, add static asserts
This commit is contained in:
		
							parent
							
								
									6da0cb3544
								
							
						
					
					
						commit
						7640c038f3
					
				
							
								
								
									
										111
									
								
								include/ss/setup.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								include/ss/setup.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| #pragma once | ||||
| #include "type_traits.hpp" | ||||
| #include <array> | ||||
| 
 | ||||
| namespace ss { | ||||
| 
 | ||||
| template <char... Cs> | ||||
| struct matcher { | ||||
| private: | ||||
|     template <char X, char... Xs> | ||||
|     static bool match_impl(char c) { | ||||
|         if constexpr (sizeof...(Xs) != 0) { | ||||
|             return (c == X) || match_impl<Xs...>(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<Cs...>(c); | ||||
|     } | ||||
| 
 | ||||
|     constexpr static bool enabled = true; | ||||
|     constexpr static std::array<char, sizeof...(Cs)> matches{Cs...}; | ||||
|     static_assert(contains_string_terminator(), | ||||
|                   "string terminator cannot be used as a match character"); | ||||
| }; | ||||
| 
 | ||||
| template <typename FirstMatcher, typename SecondMatcher> | ||||
| 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<char, 1> matches{'\0'}; | ||||
|     static bool match(char c) = delete; | ||||
| }; | ||||
| 
 | ||||
| template <char C> | ||||
| struct quote : matcher<C> {}; | ||||
| 
 | ||||
| template <char... Cs> | ||||
| struct trim : matcher<Cs...> {}; | ||||
| 
 | ||||
| template <char... Cs> | ||||
| struct escape : matcher<Cs...> {}; | ||||
| 
 | ||||
| template <typename T, template <char...> class Template> | ||||
| struct is_instance_of_matcher { | ||||
|     constexpr static bool value = false; | ||||
| }; | ||||
| 
 | ||||
| template <char... Ts, template <char...> class Template> | ||||
| struct is_instance_of_matcher<Template<Ts...>, Template> { | ||||
|     constexpr static bool value = true; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename... Ts> | ||||
| struct get_matcher; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename T, typename... Ts> | ||||
| struct get_matcher<Matcher, T, Ts...> { | ||||
|     using type = | ||||
|         typename ternary<is_instance_of_matcher<T, Matcher>::value, T, | ||||
|                          typename get_matcher<Matcher, Ts...>::type>::type; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher> | ||||
| struct get_matcher<Matcher> { | ||||
|     using type = Matcher<'\0'>; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename... Ts> | ||||
| using get_matcher_t = typename get_matcher<Matcher, Ts...>::type; | ||||
| 
 | ||||
| template <typename... Ts> | ||||
| struct setup { | ||||
|     using quote = get_matcher_t<quote, Ts...>; | ||||
|     using trim = get_matcher_t<trim, Ts...>; | ||||
|     using escape = get_matcher_t<escape, Ts...>; | ||||
| 
 | ||||
| #define ASSERT_MSG "cannot have the same character in multiple matchers" | ||||
|     static_assert(!matches_intersect<quote, trim>(), ASSERT_MSG); | ||||
|     static_assert(!matches_intersect<trim, escape>(), ASSERT_MSG); | ||||
|     static_assert(!matches_intersect<escape, quote>(), ASSERT_MSG); | ||||
| #undef ASSERT_MSG | ||||
| }; | ||||
| 
 | ||||
| template <typename... Ts> | ||||
| struct setup<setup<Ts...>> : setup<Ts...> {}; | ||||
| 
 | ||||
| } /* ss */ | ||||
| @ -1,4 +1,5 @@ | ||||
| #pragma once | ||||
| #include "setup.hpp" | ||||
| #include "type_traits.hpp" | ||||
| #include <cstdlib> | ||||
| #include <cstring> | ||||
| @ -6,78 +7,6 @@ | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace ss { | ||||
| template <char... Cs> | ||||
| struct matcher { | ||||
| private: | ||||
|     template <char X, char... Xs> | ||||
|     static bool match_impl(char c) { | ||||
|         if constexpr (sizeof...(Xs) != 0) { | ||||
|             return (c == X) || match_impl<Xs...>(c); | ||||
|         } | ||||
|         return (c == X); | ||||
|     } | ||||
| 
 | ||||
| public: | ||||
|     static bool match(char c) { | ||||
|         return match_impl<Cs...>(c); | ||||
|     } | ||||
|     constexpr static bool enabled = true; | ||||
| }; | ||||
| 
 | ||||
| template <> | ||||
| class matcher<'\0'> { | ||||
| public: | ||||
|     constexpr static bool enabled = false; | ||||
|     static bool match(char c) = delete; | ||||
| }; | ||||
| 
 | ||||
| template <char C> | ||||
| struct quote : matcher<C> {}; | ||||
| 
 | ||||
| template <char... Cs> | ||||
| struct trim : matcher<Cs...> {}; | ||||
| 
 | ||||
| template <char... Cs> | ||||
| struct escape : matcher<Cs...> {}; | ||||
| 
 | ||||
| template <typename T, template <char...> class Template> | ||||
| struct is_instance_of_matcher { | ||||
|     constexpr static bool value = false; | ||||
| }; | ||||
| 
 | ||||
| template <char... Ts, template <char...> class Template> | ||||
| struct is_instance_of_matcher<Template<Ts...>, Template> { | ||||
|     constexpr static bool value = true; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename... Ts> | ||||
| struct get_matcher; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename T, typename... Ts> | ||||
| struct get_matcher<Matcher, T, Ts...> { | ||||
|     using type = | ||||
|         typename ternary<is_instance_of_matcher<T, Matcher>::value, T, | ||||
|                          typename get_matcher<Matcher, Ts...>::type>::type; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher> | ||||
| struct get_matcher<Matcher> { | ||||
|     using type = Matcher<'\0'>; | ||||
| }; | ||||
| 
 | ||||
| template <template <char...> class Matcher, typename... Ts> | ||||
| using get_matcher_t = typename get_matcher<Matcher, Ts...>::type; | ||||
| 
 | ||||
| // TODO add static asserts
 | ||||
| template <typename... Ts> | ||||
| struct setup { | ||||
|     using quote = get_matcher_t<quote, Ts...>; | ||||
|     using trim = get_matcher_t<trim, Ts...>; | ||||
|     using escape = get_matcher_t<escape, Ts...>; | ||||
| }; | ||||
| 
 | ||||
| template <typename... Ts> | ||||
| struct setup<setup<Ts...>> : setup<Ts...> {}; | ||||
| 
 | ||||
| using string_range = std::pair<const char*, const char*>; | ||||
| using split_input = std::vector<string_range>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user