|
|
@@ -13,12 +13,12 @@
|
|
|
|
|
|
namespace Carbon {
|
|
|
|
|
|
-/// A persistent stack data structure.
|
|
|
-///
|
|
|
-/// - Note: this data structure leaks memory.
|
|
|
+// A persistent stack data structure.
|
|
|
+//
|
|
|
+// - Note: this data structure leaks memory.
|
|
|
template <class T>
|
|
|
struct Stack {
|
|
|
- /// A forward iterator over elements of a `Stack`.
|
|
|
+ // A forward iterator over elements of a `Stack`.
|
|
|
struct Iterator {
|
|
|
using value_type = T;
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
@@ -46,32 +46,32 @@ struct Stack {
|
|
|
ListNode<T>* p;
|
|
|
};
|
|
|
|
|
|
- /// The position of the first/`Top()` element, or `end()` if
|
|
|
- /// `this->IsEmpty()`.
|
|
|
+ // The position of the first/`Top()` element, or `end()` if
|
|
|
+ // `this->IsEmpty()`.
|
|
|
auto begin() const -> Iterator { return Iterator(head); }
|
|
|
|
|
|
- /// The position one past that of the last element.
|
|
|
+ // The position one past that of the last element.
|
|
|
auto end() const -> Iterator { return Iterator(nullptr); }
|
|
|
|
|
|
- /// Creates an empty instance.
|
|
|
+ // Creates an empty instance.
|
|
|
Stack() { head = nullptr; }
|
|
|
|
|
|
- /// Creates an instance containing just `x`.
|
|
|
+ // Creates an instance containing just `x`.
|
|
|
Stack(T x) : Stack() { Push(x); }
|
|
|
|
|
|
- /// Pushes `x` onto the top of the stack.
|
|
|
+ // Pushes `x` onto the top of the stack.
|
|
|
void Push(T x) { head = new ListNode<T>(x, head); }
|
|
|
|
|
|
- /// Returns a copy of `*this`, with `x` pushed onto the top.
|
|
|
+ // Returns a copy of `*this`, with `x` pushed onto the top.
|
|
|
auto Pushing(T x) const -> Stack {
|
|
|
auto r = *this;
|
|
|
r.Push(x);
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- /// Removes and returns the top element of the stack.
|
|
|
- ///
|
|
|
- /// - Requires: !this->IsEmpty()
|
|
|
+ // Removes and returns the top element of the stack.
|
|
|
+ //
|
|
|
+ // - Requires: !this->IsEmpty()
|
|
|
auto Pop() -> T {
|
|
|
assert(!IsEmpty() && "Can't pop from empty stack.");
|
|
|
auto r = head->curr;
|
|
|
@@ -79,9 +79,9 @@ struct Stack {
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- /// Removes the top `n` elements of the stack.
|
|
|
- ///
|
|
|
- /// - Requires: n >= 0 && n <= Count()
|
|
|
+ // Removes the top `n` elements of the stack.
|
|
|
+ //
|
|
|
+ // - Requires: n >= 0 && n <= Count()
|
|
|
void Pop(int n) {
|
|
|
assert(n >= 0 && "Negative pop count disallowed.");
|
|
|
while (n--) {
|
|
|
@@ -90,29 +90,29 @@ struct Stack {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// Returns a copy of `*this`, sans the top element.
|
|
|
- ///
|
|
|
- /// - Requires: !this->IsEmpty()
|
|
|
+ // Returns a copy of `*this`, sans the top element.
|
|
|
+ //
|
|
|
+ // - Requires: !this->IsEmpty()
|
|
|
auto Popped() const -> Stack {
|
|
|
auto r = *this;
|
|
|
r.Pop();
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- /// Returns the top element of the stack.
|
|
|
- ///
|
|
|
- /// - Requires: !this->IsEmpty()
|
|
|
+ // Returns the top element of the stack.
|
|
|
+ //
|
|
|
+ // - Requires: !this->IsEmpty()
|
|
|
auto Top() const -> T {
|
|
|
assert(!IsEmpty() && "Empty stack has no Top().");
|
|
|
return head->curr;
|
|
|
}
|
|
|
|
|
|
- /// Returns `true` iff `Count() > 0`.
|
|
|
+ // Returns `true` iff `Count() > 0`.
|
|
|
auto IsEmpty() const -> bool { return head == nullptr; }
|
|
|
|
|
|
- /// Returns `true` iff `Count() > n`.
|
|
|
- ///
|
|
|
- /// - Complexity: O(`n`)
|
|
|
+ // Returns `true` iff `Count() > n`.
|
|
|
+ //
|
|
|
+ // - Complexity: O(`n`)
|
|
|
auto CountExceeds(int n) const -> bool {
|
|
|
if (n < 0)
|
|
|
return true;
|
|
|
@@ -125,11 +125,11 @@ struct Stack {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- /// Returns the number of elements in `*this`.
|
|
|
+ // Returns the number of elements in `*this`.
|
|
|
auto Count() const -> int { return std::distance(begin(), end()); }
|
|
|
|
|
|
private:
|
|
|
- /// An linked list of cells containing the elements of self.
|
|
|
+ // A linked list of cells containing the elements of self.
|
|
|
ListNode<T>* head;
|
|
|
};
|
|
|
|