Skip to content

Instantly share code, notes, and snippets.

@Georgiy-Tugai
Last active August 29, 2015 14:20
Show Gist options
  • Save Georgiy-Tugai/1f4a76e13f1e2d6847fb to your computer and use it in GitHub Desktop.
Save Georgiy-Tugai/1f4a76e13f1e2d6847fb to your computer and use it in GitHub Desktop.
attempt at iterator
namespace core {
class List_V; // Virtual class representing Common Lisp LIST
};
namespace gctools {
typedef smart_ptr<core::List_V> List_sp;
class List_sp_iterator_nil;
class List_sp_iterator {
public:
List_sp_iterator(List_sp *ptr) { ptr = ptr; }
List_sp_iterator &operator++() {
assert(this->ptr->consp());
this->ptr = smart_ptr<List_V>(cons_cdr(*(this->ptr)));
return *this;
}
List_sp_iterator &operator++(int) { // postfix
auto clone = new List_sp_iterator(*this);
++*this;
return *clone;
}
bool operator==(const List_sp_iterator &b) const {
if (b->ptr->consp())
return *ptr == *(b->ptr);
else
return !ptr->consp();
}
bool operator==(const List_sp_iterator_nil &b) const { return !ptr->consp(); }
bool operator!=(const List_sp_iterator &b) const { return !(*this == b); }
bool operator!=(const List_sp_iterator_nil &b) const { return ptr->consp() }
List_sp &operator->() { return *ptr; }
List_sp &operator->() const { return *ptr; }
List_sp &operator*() { return **ptr }
private:
const List_sp *ptr;
friend class List_sp;
};
class List_sp_iterator_nil : public List_sp_iterator {
List_sp_iterator_nil() : List_sp_iterator(nullptr){};
bool operator==(const List_sp_iterator &b) const { return !b->consp(); }
bool operator!=(const List_sp_iterator &b) const { return b->consp(); }
List_sp &operator->() = delete;
List_sp &operator->() = delete;
List_sp &operator*() = delete;
List_sp &operator++() = delete;
List_sp &operator++(int) = delete;
};
template <> class smart_ptr<core::List_V> {
public:
typedef core::T_O
Type; // The best common type for both Cons_O and Symbol_O is T_O
Type *theObject;
public:
List_sp_iterator begin() { return List_sp_iterator(this); }
List_sp_iterator end() { return List_sp_iterator_nil(); }
public:
//! The default constructor returns an invalid smart_ptr
smart_ptr() : theObject(NULL){};
// Constructor that takes Cons_O* assumes its untagged
explicit inline smart_ptr(core::Cons_O *ptr)
: theObject(tag_cons<Type>(ptr)) {
GCTOOLS_ASSERT((reinterpret_cast<uintptr_t>(ptr) & tag_mask) == 0);
};
explicit inline smart_ptr(core::Symbol_O *ptr)
: theObject(tag_other<Type>(ptr)) {
GCTOOLS_ASSERT((reinterpret_cast<uintptr_t>(ptr) & tag_mask) == 0);
};
/*! Constructor that takes Tagged assumes that the pointer is tagged.
Any ptr passed to this constructor must have the CONS tag.
*/
explicit inline smart_ptr(Tagged ptr)
: theObject(reinterpret_cast<Type *>(ptr)) {
GCTOOLS_ASSERT(tagged_consp<Type>(reinterpret_cast<Type *>(ptr)) ||
tagged_nilp<Type>(reinterpret_cast<Type *>(ptr)));
};
public:
explicit operator bool() const { return this->theObject != NULL; }
public:
void reset_() { this->theObject = NULL; };
inline bool otherp() const { return tagged_otherp<Type>(this->theObject); };
inline bool consp() const {
return tagged_consp(this->theObject) || tagged_nilp(this->theObject);
};
inline bool objectp() const { return this->otherp() || this->consp(); };
// inline bool nilp() const { return tagged_nilp(this->theObject); };
// inline bool notnilp() const { return this->nilp(); };
inline bool isTrue() const { return !this->nilp(); };
inline bool unboundp() const { return tagged_unboundp(this->theObject); };
inline bool valid() const { return this->consp() || this->nilp(); };
operator smart_ptr<core::T_O>() const {
return smart_ptr<Type>((Tagged) const_cast<Type *const>(
reinterpret_cast<Type *>(this->theObject)));
};
Type *untag_object() const {
GCTOOLS_ASSERT(this->otherp() || this->consp());
if (this->consp()) {
return untag_cons<Type>(this->theObject);
} else {
if (this->nilp()) {
return tag_nil<Type>();
}
}
THROW_HARD_ERROR(BF("Figure out what to do when untag_object doesn't have "
"a Cons_O or NIL"));
}
inline void swap(smart_ptr<T> &other) {
T *temp;
temp = this->theObject;
this->theObject = other.theObject;
other.theObject = temp;
}
/*! Dereferencing operator - remove the other tag */
inline Type *operator->() {
GCTOOLS_ASSERT(this->objectp());
return this->untag_object();
};
inline Type *operator->() const {
GCTOOLS_ASSERT(this->objectp());
return this->untag_object();
};
inline Type &operator*() {
GCTOOLS_ASSERT(this->objectp());
return *(this->untag_object());
};
core::T_O *raw_() const { return reinterpret_cast<Type *>(this->theObject); }
bool _NULLp() const { return this->theObject == NULL; };
template <class U> inline bool operator==(smart_ptr<U> const other) const {
return this->theObject == other.theObject;
}
template <class U> inline bool operator!=(smart_ptr<U> const other) const {
return this->theObject != other.theObject;
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment