string_stack.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "string_stack.h"
  2. #include <algorithm> // std::min
  3. #include <utility> // std::move
  4. namespace simple::file::string_stack
  5. {
  6. std::string::size_type top(const std::string& stack, const std::string& delimiters)
  7. {
  8. auto end = stack.find_last_not_of(delimiters);
  9. auto top = stack.find_last_of(delimiters, end);
  10. // this edge case turns out to be handled rather nicely by the usual case, but leaving the code commented here to indicate the intent
  11. // if(std::string::npos == top)
  12. // top = 0;
  13. // else
  14. ++top;
  15. return top;
  16. }
  17. std::string pop(std::string& stack, const std::string& delimiters)
  18. {
  19. auto _top = top(stack, delimiters);
  20. auto name = stack.substr(_top);
  21. stack.resize(_top);
  22. return name;
  23. }
  24. void drop(std::string& stack, const std::string& delimiters)
  25. {
  26. stack.resize(top(stack, delimiters));
  27. }
  28. void push(std::string& stack, const std::string& content, const std::string& delimiters)
  29. {
  30. if(!stack.empty() && delimiters.find(stack.back()) == std::string::npos)
  31. stack += delimiters.front();
  32. stack += content;
  33. }
  34. unsigned manipulator::dec(unsigned amount)
  35. {
  36. return size -= std::min(size, amount);
  37. }
  38. manipulator::manipulator(std::string& on, std::string delimiters)
  39. : stack(&on), delimiters(delimiters)
  40. {}
  41. manipulator::manipulator(manipulator&& other) : manipulator(other)
  42. {
  43. other.release();
  44. }
  45. manipulator& manipulator::operator=(manipulator&& other)
  46. {
  47. manipulator tmp(*this); // call destructor plz am too lazy
  48. *this = other;
  49. other.release();
  50. return *this;
  51. }
  52. manipulator::~manipulator()
  53. {
  54. while(size)
  55. drop();
  56. }
  57. void manipulator::release()
  58. {
  59. size = 0;
  60. }
  61. std::string manipulator::pop()
  62. {
  63. dec();
  64. return string_stack::pop(*stack, delimiters);
  65. };
  66. void manipulator::drop()
  67. {
  68. string_stack::drop(*stack, delimiters);
  69. dec();
  70. };
  71. manipulator& manipulator::push(const std::string& value) &
  72. {
  73. if(!value.empty())
  74. {
  75. string_stack::push(*stack, value, delimiters);
  76. ++size;
  77. }
  78. return *this;
  79. }
  80. manipulator&& manipulator::push(const std::string& value) &&
  81. {
  82. push(value);
  83. return std::move(*this);
  84. }
  85. } // namespace simple::file::string_stack