Skip to content

Instantly share code, notes, and snippets.

@pallas
Last active March 26, 2020 03:11
Show Gist options
  • Save pallas/9628557 to your computer and use it in GitHub Desktop.
Save pallas/9628557 to your computer and use it in GitHub Desktop.
C++ intrusive stack
// All rights reserved,
// Derrick Pallas
// License: zlib
#ifndef INTRUSIVE_STACK_H
#define INTRUSIVE_STACK_H
#include <cassert>
#include <cstddef>
template <class X>
struct intrusive_stack_link {
intrusive_stack_link() : p(NULL) { }
~intrusive_stack_link() { assert(!p); }
typedef intrusive_stack_link type;
template <class T, typename intrusive_stack_link<T>::type T::*link>
friend class intrusive_stack;
bool bound() const { return p; }
private:
X* p;
};
template <class T, typename intrusive_stack_link<T>::type T::*link>
class intrusive_stack {
public:
intrusive_stack() : head(reinterpret_cast<T*>(0xbad)) { }
~intrusive_stack() { assert(empty()); }
bool empty() const { return head == reinterpret_cast<const T*>(0xbad); }
intrusive_stack & push(T* t) {
assert(!(t->*link).bound());
(t->*link).p = head;
head = t;
assert((t->*link).bound());
assert(!empty());
return *this;
}
T* pop() {
assert(!empty());
T* t = head;
assert((t->*link).bound());
head = (t->*link).p;
(t->*link).p = NULL;
assert(!(t->*link).bound());
return t;
}
private:
intrusive_stack(const intrusive_stack &);
intrusive_stack & operator=(const intrusive_stack &);
T * head;
};
#endif//INTRUSIVE_STACK_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment