123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- #include "string_stack.h"
- #include <algorithm> // std::min
- #include <utility> // std::move
- namespace simple::file::string_stack
- {
- std::string::size_type top(const std::string& stack, const std::string& delimiters)
- {
- auto end = stack.find_last_not_of(delimiters);
- auto top = stack.find_last_of(delimiters, end);
- // this edge case turns out to be handled rather nicely by the usual case, but leaving the code commented here to indicate the intent
- // if(std::string::npos == top)
- // top = 0;
- // else
- ++top;
- return top;
- }
- std::string pop(std::string& stack, const std::string& delimiters)
- {
- auto _top = top(stack, delimiters);
- auto name = stack.substr(_top);
- stack.resize(_top);
- return name;
- }
- void drop(std::string& stack, const std::string& delimiters)
- {
- stack.resize(top(stack, delimiters));
- }
- void push(std::string& stack, const std::string& content, const std::string& delimiters)
- {
- if(!stack.empty() && delimiters.find(stack.back()) == std::string::npos)
- stack += delimiters.front();
- stack += content;
- }
- unsigned manipulator::dec(unsigned amount)
- {
- return size -= std::min(size, amount);
- }
- manipulator::manipulator(std::string& on, std::string delimiters)
- : stack(&on), delimiters(delimiters)
- {}
- manipulator::manipulator(manipulator&& other) : manipulator(other)
- {
- other.release();
- }
- manipulator& manipulator::operator=(manipulator&& other)
- {
- manipulator tmp(*this); // call destructor plz am too lazy
- *this = other;
- other.release();
- return *this;
- }
- manipulator::~manipulator()
- {
- while(size)
- drop();
- }
- void manipulator::release()
- {
- size = 0;
- }
- std::string manipulator::pop()
- {
- dec();
- return string_stack::pop(*stack, delimiters);
- };
- void manipulator::drop()
- {
- string_stack::drop(*stack, delimiters);
- dec();
- };
- manipulator& manipulator::push(const std::string& value) &
- {
- if(!value.empty())
- {
- string_stack::push(*stack, value, delimiters);
- ++size;
- }
- return *this;
- }
- manipulator&& manipulator::push(const std::string& value) &&
- {
- push(value);
- return std::move(*this);
- }
- } // namespace simple::file::string_stack
|