#ifndef Rice__Array__ipp_ #define Rice__Array__ipp_ #include "protect.hpp" inline Rice::Array:: Array() : Builtin_Object(protect(rb_ary_new)) { } inline Rice::Array:: Array(Object v) : Builtin_Object(v) { } inline Rice::Array:: Array(VALUE v) : Builtin_Object(v) { } template inline Rice::Array:: Array(Iter_T it, Iter_T end) : Builtin_Object(protect(rb_ary_new)) { for(; it != end; ++it) { push(*it); } } template inline Rice::Array:: Array(T const (& a)[n]) : Builtin_Object(protect(rb_ary_new)) { for(size_t j = 0; j < n; ++j) { push(a[j]); } } inline size_t Rice::Array:: size() const { return RARRAY_LEN(this->value()); } inline Rice::Object Rice::Array:: operator[](ptrdiff_t index) const { return protect(rb_ary_entry, value(), position_of(index)); } inline Rice::Array::Proxy Rice::Array:: operator[](ptrdiff_t index) { return Proxy(*this, position_of(index)); } template inline Rice::Object Rice::Array:: push(T const & obj) { return protect(rb_ary_push, value(), to_ruby(obj)); } inline Rice::Object Rice::Array:: pop() { return protect(rb_ary_pop, value()); } template inline Rice::Object Rice::Array:: unshift(T const & obj) { return protect(rb_ary_unshift, value(), to_ruby(obj)); } inline Rice::Object Rice::Array:: shift() { return protect(rb_ary_shift, value()); } inline size_t Rice::Array:: position_of(ptrdiff_t index) const { if(index < 0) { return size() + index; } else { return static_cast(index); } } inline Rice::Array::Proxy:: Proxy(Array array, size_t index) : array_(array) , index_(index) { } inline Rice::Array::Proxy:: operator Rice::Object() const { return protect(rb_ary_entry, array_.value(), index_); } inline VALUE Rice::Array::Proxy:: value() const { return protect(rb_ary_entry, array_.value(), index_); } template Rice::Object Rice::Array::Proxy:: operator=(T const & value) { Object o = to_ruby(value); rb_ary_store(array_.value(), index_, o.value()); return o; } template inline Rice::Array::Iterator:: Iterator(Array_Ref_T array, size_t index) : array_(array) , index_(index) { } template template inline Rice::Array::Iterator:: Iterator(Iterator const & rhs) : array_(rhs.array()) , index_(rhs.index()) , tmp_() { } template template inline Rice::Array::Iterator & Rice::Array::Iterator:: operator=(Iterator const & rhs) { array_ = rhs.array_; index_ = rhs.index_; return *this; } template inline Rice::Array::Iterator & Rice::Array::Iterator:: operator++() { ++index_; return *this; } template inline Rice::Array::Iterator Rice::Array::Iterator:: operator++(int) { Array copy(*this); ++(*this); return *this; } template inline Value_T Rice::Array::Iterator:: operator*() { return array_[index_]; } template inline Rice::Object * Rice::Array::Iterator:: operator->() { tmp_ = array_[index_]; return &tmp_; } template template inline bool Rice::Array::Iterator:: operator==(Iterator const & rhs) const { return array_.value() == rhs.array_.value() && index_ == rhs.index_; } template template inline bool Rice::Array::Iterator:: operator!=(Iterator const & rhs) const { return !(*this == rhs); } template Array_Ref_T Rice::Array::Iterator:: array() const { return array_; } template size_t Rice::Array::Iterator:: index() const { return index_; } inline Rice::Array::iterator Rice::Array:: begin() { return iterator(*this, 0); } inline Rice::Array::const_iterator Rice::Array:: begin() const { return const_iterator(*this, 0); } inline Rice::Array::iterator Rice::Array:: end() { return iterator(*this, size()); } inline Rice::Array::const_iterator Rice::Array:: end() const { return const_iterator(*this, size()); } #endif // Rice__Array__ipp_