demangle_vector.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <iterator>
  4. #include <string>
  5. #include "simple/support/algorithm.hpp"
  6. using namespace std;
  7. using simple::support::make_range;
  8. using strange = simple::support::range<string::iterator>;
  9. ostream& operator<<(ostream& output, const strange & value)
  10. {
  11. for(auto&& ch : value)
  12. output << ch;
  13. return output;
  14. }
  15. using char_ptr = istream_iterator<char>;
  16. const char_ptr char_end = char_ptr();
  17. const string keyword = "simple::geom::vector<";
  18. // TODO: specify depth of counter?
  19. // TODO: remember the position of found open
  20. class in_scope
  21. {
  22. public:
  23. in_scope(char open, char close, char match)
  24. : open(open), close(close), match(match), counter(1) {}
  25. in_scope(char open, char close)
  26. : in_scope(open, close, close) {};
  27. bool operator()(char current)
  28. {
  29. if(counter == 0)
  30. return false;
  31. if(counter == 1 && current == match)
  32. return true; // TODO: don't return here to process counts if match is same as close(default) or open, so that in scope is reentrant
  33. if(current == close)
  34. {
  35. --counter;
  36. }
  37. else if(current == open)
  38. {
  39. ++counter;
  40. }
  41. return false;
  42. }
  43. private:
  44. const char open, close, match;
  45. int counter;
  46. };
  47. template<typename ForwardIterator, typename OutputIterator, typename Functor>
  48. ForwardIterator copy_until(ForwardIterator first, ForwardIterator last, OutputIterator out, Functor end_condition)
  49. {
  50. while(first != last)
  51. {
  52. const typename ForwardIterator::value_type& value = *first;
  53. if(end_condition(value))
  54. break;
  55. *out++ = value;
  56. ++first;
  57. }
  58. return first;
  59. }
  60. void shorten_vector_stuff(strange stuff)
  61. {
  62. auto comma = find_if(stuff.begin(), stuff.end(),
  63. in_scope('<', '>', ','));
  64. auto second_comma = find_if(comma+1, stuff.end(),
  65. in_scope('<', '>', ','));
  66. strange til_comma {stuff.begin(), comma};
  67. auto nested_vector = search(til_comma.begin(), til_comma.end(), keyword.begin(), keyword.end());
  68. cout << "<";
  69. if(nested_vector != til_comma.end())
  70. {
  71. nested_vector += keyword.size();
  72. cout << "vector";
  73. shorten_vector_stuff({nested_vector, til_comma.end() - 1});
  74. }
  75. else
  76. cout << til_comma;
  77. cout << strange{comma, second_comma} << ">";
  78. }
  79. int main(int, char const*const*)
  80. {
  81. cin >> noskipws;
  82. string match = "";
  83. char_ptr i(cin);
  84. while(i != char_end)
  85. {
  86. char current = *i;
  87. if(current == keyword[match.size()])
  88. {
  89. match.push_back(current);
  90. if(match.size() == keyword.size())
  91. {
  92. cout << "vector";
  93. ++i;
  94. string stuff = "";
  95. copy_until(i, char_end, back_inserter(stuff), in_scope('<','>'));
  96. shorten_vector_stuff(make_range(stuff));
  97. match.clear();
  98. }
  99. }
  100. else
  101. {
  102. cout << match << current;
  103. match.clear();
  104. }
  105. ++i;
  106. }
  107. return 0;
  108. }