pattern_parse.hpp (4286B)
1 #ifndef UUID_5F4B4145_C89A_4241_8A9C_B8DBBB568F43 2 #define UUID_5F4B4145_C89A_4241_8A9C_B8DBBB568F43 3 #pragma once 4 5 #include "pattern.hpp" 6 #include <libshit/meta_utils.hpp> 7 8 namespace Neptools 9 { 10 11 namespace PatternParse 12 { 13 14 template <char C, typename Enable = void> 15 struct HexValue; 16 17 template <char C> 18 struct HexValue<C, typename std::enable_if_t<C >= '0' && C <= '9'>> 19 : std::integral_constant<unsigned, C - '0'> {}; 20 21 template <char C> 22 struct HexValue<C, typename std::enable_if_t<C >= 'A' && C <= 'F'>> 23 : std::integral_constant<unsigned, C + 10 - 'A'> {}; 24 25 template <char C> 26 struct HexValue<C, typename std::enable_if_t<C >= 'a' && C <= 'f'>> 27 : std::integral_constant<unsigned, C + 10 - 'a'> {}; 28 29 template <char C> 30 constexpr auto HexValueV = HexValue<C>::value; 31 32 template <unsigned Acc, char... Chars> struct FromHex; 33 template <unsigned Acc, char A, char... Chars> 34 struct FromHex<Acc, A, Chars...> 35 : std::integral_constant< 36 unsigned, FromHex< 37 Acc * 16 + HexValueV<A>, Chars...>::value> {}; 38 39 template <unsigned Acc> 40 struct FromHex<Acc> : std::integral_constant<unsigned, Acc> {}; 41 42 template <char... Chars> 43 constexpr auto FromHexV = FromHex<0, Chars...>::value; 44 45 template <Byte... Bytes> struct ByteSequence 46 { 47 static constexpr size_t size = sizeof...(Bytes); 48 // fucking retards, why can't I have a zero sized stack based array 49 static constexpr Byte seq[size==0?1:size] = { Bytes... }; 50 51 template <Byte C> 52 using Append = ByteSequence<Bytes..., C>; 53 }; 54 template <Byte... Bytes> constexpr Byte ByteSequence<Bytes...>::seq[]; 55 56 template <typename PatternBytes, typename MaskBytes> 57 struct Pattern : public ::Neptools::Pattern 58 { 59 template <Byte Pat, Byte Mask> 60 using Append = Pattern<typename PatternBytes::template Append<Pat>, 61 typename MaskBytes::template Append<Mask>>; 62 63 constexpr Pattern() noexcept : ::Neptools::Pattern{pattern, mask, size} {} 64 65 static constexpr auto pattern = PatternBytes::seq; 66 static constexpr auto mask = MaskBytes::seq; 67 static constexpr auto size = PatternBytes::size; 68 }; 69 70 template <typename Pat, char... Args> struct PatternParse; 71 72 template <typename Pat, char... Args> 73 struct PatternParse<Pat, '?', '?', ' ', Args...> 74 { 75 using value = typename PatternParse< 76 typename Pat::template Append<0x00, 0x00>, 77 Args...>::value; 78 }; 79 80 template <typename Pat, char... Args> 81 struct PatternParse<Pat, '?', ' ', Args...> 82 { 83 using value = typename PatternParse< 84 typename Pat::template Append<0x00, 0x00>, 85 Args...>::value; 86 }; 87 88 template <typename Pat, char A, char B, char... Args> 89 struct PatternParse<Pat, A, B, ' ', Args...> 90 { 91 using value = typename PatternParse< 92 typename Pat::template Append<FromHexV<A, B>, 0xff>, 93 Args...>::value; 94 }; 95 96 template <typename Pat, char A, char... Args> 97 struct PatternParse<Pat, A, ' ', Args...> 98 { 99 using value = typename PatternParse< 100 typename Pat::template Append<FromHexV<A>, 0xff>, 101 Args...>::value; 102 }; 103 104 template <typename Pat, char A, char B, char C, char D, char... Args> 105 struct PatternParse<Pat, A, B, '/', C, D, ' ', Args...> 106 { 107 static constexpr auto Val = FromHexV<A, B>; 108 static constexpr auto Mask = FromHexV<C, D>; 109 using value = typename PatternParse< 110 typename Pat::template Append<Val & Mask, Mask>, 111 Args...>::value; 112 }; 113 114 template <typename Pat, char... Args> 115 struct PatternParse<Pat, ' ', Args...> 116 { 117 using value = typename PatternParse<Pat, Args...>::value; 118 }; 119 120 template <typename Pat> 121 struct PatternParse<Pat> 122 { 123 using value = Pat; 124 }; 125 126 template <char... Bytes> 127 using DoPatternParse = typename PatternParse< 128 Pattern<ByteSequence<>, ByteSequence<>>, Bytes..., ' '>::value; 129 130 template <typename X, size_t... Idx> 131 DoPatternParse<X::Get(Idx)...> ToPattern(std::index_sequence<Idx...>) 132 { return {}; } 133 134 } 135 136 #define NEPTOOLS_PATTERN(str) \ 137 LIBSHIT_LITERAL_CHARPACK(::Neptools::PatternParse::DoPatternParse, str) 138 139 } 140 #endif