/vm/builtin/list.cpp
C++ | 133 lines | 88 code | 34 blank | 11 comment | 16 complexity | 957078a1a6ef62da759c50d9165a8212 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1
- #include "builtin/class.hpp"
- #include "builtin/fixnum.hpp"
- #include "builtin/list.hpp"
- #include "object_utils.hpp"
- #include "ontology.hpp"
- namespace rubinius {
- /* Returns true if the List is empty, contains no elements. */
- bool List::empty_p() {
- return count_->to_native() == 0;
- }
- /* Returns the number of elements in the List. */
- size_t List::size() {
- return count_->to_native();
- }
- /* Register the List and List::Node classes as globals */
- void List::init(STATE) {
- Class* cls;
- cls = ontology::new_class_under(state, "List", G(rubinius));
- GO(list).set(cls);
- cls->set_object_type(state, ListType);
- GO(list_node).set(ontology::new_class_under(state,
- "Node", cls));
- G(list_node)->set_object_type(state, ListNodeType);
- }
- /* Create a new List object, containing no elements. */
- List* List::create(STATE) {
- List* list = state->new_object<List>(G(list));
- list->count(state, Fixnum::from(0));
- return list;
- }
- /* Append +obj+ to the current List. */
- void List::append(STATE, Object* obj) {
- ListNode* node = state->new_object<ListNode>(G(list_node));
- node->object(state, obj);
- ListNode* cur_last = last_;
- if(!cur_last->nil_p()) {
- cur_last->next(state, node);
- }
- last(state, node);
- if(first_->nil_p()) {
- first(state, node);
- }
- count(state, Integer::from(state, count_->to_native() + 1));
- }
- /* Return the +index+ numbered element from the beginning. */
- Object* List::locate(STATE, size_t index) {
- ListNode* cur = first_;
- while(index > 0) {
- if(cur->nil_p()) return cNil;
- cur = cur->next();
- index--;
- }
- if(cur->nil_p()) return cNil;
- return cur->object();
- }
- /* Return the first element in the list and remove it, moving all
- * other elements forward. */
- Object* List::shift(STATE) {
- if(empty_p()) return cNil;
- count(state, Integer::from(state, count_->to_native() - 1));
- ListNode* n = first_;
- first(state, first_->next());
- if(last_ == n) {
- last(state, nil<ListNode>());
- }
- return n->object();
- }
- /* Search the List for +obj+ and remove all instances of it.
- *
- * Returns the number of elements removed. */
- size_t List::remove(STATE, const Object* obj) {
- if(empty_p()) return 0;
- size_t deleted = 0, counted = 0;
- ListNode* node = first_;
- ListNode* lst = nil<ListNode>();
- ListNode* nxt;
- while(!node->nil_p()) {
- nxt = node->next();
- if(node->object() == obj) {
- deleted++;
- if(lst->nil_p()) {
- first(state, nxt);
- } else {
- lst->next(state, nxt);
- }
- if(last_ == node) {
- last(state, lst);
- }
- lst = nil<ListNode>();
- } else {
- counted++;
- lst = node;
- }
- node = nxt;
- }
- count(state, Integer::from(state, counted));
- return deleted;
- }
- }