Advertisement
zhangsongcui

StrFormater

Aug 3rd, 2012
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.33 KB | None | 0 0
  1. // g++ 4.7.1, g++ 4.8 unstable, clang++ 3.1 ηΌ–θ―‘ι€šθΏ‡
  2. #if __cplusplus < 201103L
  3. #   error C++11 support is needed
  4. #endif
  5. #include <cstdio>
  6. #include <type_traits>
  7. #include <array>
  8.  
  9. constexpr int const_strcmp(const char *s1, const char *s2) {
  10.     return *s1!=*s2 || *s1 == 0 || *s2 == 0 ? *s1 - *s2 : const_strcmp(s1+1, s2+1);
  11. }
  12. // unittest
  13. static_assert(const_strcmp("asdfzxcv", "asdfzxcv") == 0, "");
  14. static_assert(const_strcmp("asdfaxcv", "asdfzxcv") < 0, "");
  15. static_assert(const_strcmp("asdf", "asdfzxcv") < 0, "");
  16.  
  17. template <typename Type, size_t Size>
  18. constexpr int const_arrcmp(const std::array<Type, Size>& arr1, const std::array<Type, Size>& arr2, const size_t idx = 0) {
  19.     return idx == Size
  20.         ? 0
  21.         : (arr1[idx] == arr2[idx]
  22.             ? const_arrcmp(arr1, arr2, idx + 1)
  23.             : arr1[idx] - arr2[idx]
  24.           );
  25. }
  26. // unittest
  27. static_assert(const_arrcmp(std::array<size_t, 4>{{1,2,3,4}}, std::array<size_t, 4>{{1,2,3,4}}) == 0, "");
  28. static_assert(const_arrcmp(std::array<size_t, 4>{{1,2,3,3}}, std::array<size_t, 4>{{1,2,3,4}}) < 0, "");
  29. static_assert(const_arrcmp(std::array<size_t, 4>{{1,2,3}}, std::array<size_t, 4>{{1,2,3,4}}) < 0, "");
  30.  
  31.  
  32. inline constexpr size_t percentCounter(const char *str) {
  33.     return *str != '\0' ? percentCounter(str + 1) + (*str == '%') : 0;
  34. }
  35. // unittest
  36. static_assert(percentCounter("%%%%") == 4, "");
  37. static_assert(percentCounter("as%fd%ae%rew%") == 4, "");
  38. static_assert(percentCounter("") == 0, "");
  39.  
  40. inline constexpr size_t percentSearch(const char *str, size_t idx, size_t pos = 0) {
  41.     return *str == '\0'
  42.         ? size_t(-1)
  43.         : (*str == '%'
  44.             ? (idx == 0
  45.                 ? pos
  46.                 : percentSearch(str + 1, idx - 1, pos + 1)
  47.               )
  48.             : percentSearch(str + 1, idx, pos + 1)
  49.           );
  50. }
  51. // unittest
  52. static_assert(percentSearch("%%%%", 1) == 1, "");
  53. static_assert(percentSearch("111%%%%", 2) == 5, "");
  54. static_assert(percentSearch("1%11", 2) == size_t(-1), "");
  55.  
  56. template <size_t argNum>
  57. class StrFormater {
  58. public:
  59.     constexpr StrFormater(const char *fStr, std::array<size_t, argNum> args): formatStr(fStr), Args(args) {}
  60.  
  61.     constexpr bool operator ==(const StrFormater& rhs) {
  62.         return const_strcmp(this->formatStr, rhs.formatStr) == 0
  63.             && const_arrcmp(this->Args, rhs.Args) == 0;
  64.     }
  65.     constexpr bool operator !=(const StrFormater& rhs) {
  66.         return !(*this == rhs);
  67.     }
  68.  
  69.     const char *const formatStr;
  70.     std::array<size_t, argNum> Args;
  71. };
  72.  
  73. template <size_t N1, size_t N2>
  74. constexpr typename std::enable_if<N1 != N2, bool>::type operator ==(const StrFormater<N1>&, const StrFormater<N2>&) {
  75.     return false;
  76. }
  77. template <size_t N1, size_t N2>
  78. constexpr typename std::enable_if<N1 != N2, bool>::type operator !=(const StrFormater<N1>&, const StrFormater<N2>&) {
  79.     return true;
  80. }
  81.  
  82. template<size_t... Seq>
  83. struct variadic_sequence
  84. {};
  85.  
  86. template <size_t Max, size_t Now = 0>
  87. struct natural_sequence {
  88.     template <size_t... Num>
  89.     using type = typename natural_sequence<Max, Now + 1>::template type<Num..., Now>;
  90. };
  91.  
  92. template <size_t Now>
  93. struct natural_sequence<Now, Now> {
  94.     template <size_t... Num>
  95.     using type = variadic_sequence<Num...>;
  96. };
  97.  
  98. template <typename>
  99. struct make_formater_helper;
  100.  
  101. template <size_t... Seq>
  102. struct make_formater_helper<variadic_sequence<Seq...>> {
  103.     static constexpr StrFormater<sizeof...(Seq)> call(const char *str) {
  104.         return StrFormater<sizeof...(Seq)>(str, std::array<size_t, sizeof...(Seq)>{ { percentSearch(str, Seq)... } });
  105.     }
  106. };
  107.  
  108. #define make_formater(FORMATSTR) (make_formater_helper<natural_sequence<percentCounter(FORMATSTR)>::type<>>::call(FORMATSTR))
  109. static_assert(make_formater("%d + %d = %d") == StrFormater<3>("%d + %d = %d", { {0, 5, 10} }), "");
  110. static_assert(make_formater("%d + %d = 1d") != StrFormater<3>("%d + %d = %d", { {0, 5, 10} }), "");
  111. static_assert(make_formater("%d + %d = %d") != StrFormater<3>("%d + %d = %d", { {0, 5, 11} }), "");
  112. static_assert(make_formater("%d + %d") != StrFormater<3>("%d + %d = %d", { {0, 5, 10} }), "");
  113. static_assert(make_formater("%d + %d") != StrFormater<2>("%d - %d", { {0, 5} }), "");
  114.  
  115. int main() {
  116.     using namespace std;
  117.     auto f = make_formater("%d + %d = %d");
  118.     for (auto i : f.Args)
  119.         printf("%zd ", i);
  120.     putchar('\n');
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement