Last active
August 29, 2015 14:20
-
-
Save Georgiy-Tugai/1f4a76e13f1e2d6847fb to your computer and use it in GitHub Desktop.
attempt at iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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