#ifndef Rice__Hash__ipp_ #define Rice__Hash__ipp_ #include "protect.hpp" #include "to_from_ruby.hpp" #include "Exception.hpp" #include "Builtin_Object.hpp" #include "detail/st.hpp" #include inline Rice::Hash:: Hash() : Builtin_Object(protect(rb_hash_new)) { } inline Rice::Hash:: Hash(Object v) : Builtin_Object(v) { } inline size_t Rice::Hash:: size() const { return RHASH_SIZE(this->value()); } inline Rice::Hash::Proxy:: Proxy(Hash hash, Object key) : hash_(hash) , key_(key) { } /* inline Rice::Hash::Proxy:: operator VALUE() const { return value(); } */ inline Rice::Hash::Proxy:: operator Rice::Object() const { return value(); } inline VALUE Rice::Hash::Proxy:: value() const { return protect(rb_hash_aref, hash_, key_); } template inline Rice::Object Rice::Hash::Proxy:: operator=(T const & value) { return protect(rb_hash_aset, hash_, key_, to_ruby(value)); } inline void Rice::Hash::Proxy:: swap(Proxy & proxy) { hash_.swap(proxy.hash_); key_.swap(proxy.key_); } template inline Rice::Hash::Proxy const Rice::Hash:: operator[](Key_T const & key) const { return Proxy(*this, to_ruby(key)); } template inline Rice::Hash::Proxy Rice::Hash:: operator[](Key_T const & key) { return Proxy(*this, to_ruby(key)); } template inline Value_T Rice::Hash:: get(Key_T const & key) { Object ruby_key(to_ruby(key)); Object value = operator[](ruby_key); try { return from_ruby(value); } catch(Exception const & ex) { String s_key(ruby_key.to_s()); throw Exception( ex, "%s while converting value for key %s", ex.what(), s_key.c_str()); } } inline Rice::Hash::Entry:: Entry(Hash hash, Object key) : key(key) , first(Hash::Entry::key) , value(hash, key) , second(Hash::Entry::value) { } inline Rice::Hash::Entry:: Entry(Entry const & entry) : key(entry.key) , first(Hash::Entry::key) , value(entry.value) , second(Hash::Entry::value) { } inline Rice::Hash::Entry & Rice::Hash::Entry:: operator=(Rice::Hash::Entry const & rhs) { Entry tmp(rhs); swap(tmp); return *this; } inline void Rice::Hash::Entry:: swap(Rice::Hash::Entry & entry) { const_cast(key).swap(const_cast(entry.key)); value.swap(entry.value); } template inline Rice::Hash::Iterator:: Iterator(Hash_Ref_T hash) : hash_(hash) , current_index_(0) , keys_(Qnil) , tmp_(hash, Qnil) { } template inline Rice::Hash::Iterator:: Iterator(Hash_Ref_T hash, int start_at) : hash_(hash) , current_index_(start_at) , keys_(Qnil) , tmp_(hash, Qnil) { } template inline Rice::Hash::Iterator:: Iterator(Iterator const & iterator) : hash_(iterator.hash_.value()) , current_index_(iterator.current_index_) , keys_(Qnil) , tmp_(iterator.hash_, Qnil) { } template template inline Rice::Hash::Iterator:: Iterator(Iterator_T const & iterator) : hash_(iterator.hash_.value()) , current_index_(iterator.current_index_) , keys_(Qnil) , tmp_(iterator.hash_, Qnil) { } template inline Rice::Hash::Iterator & Rice::Hash::Iterator:: operator=(Iterator const & iterator) { Iterator tmp(iterator); this->swap(tmp); return *this; } template inline Rice::Hash::Iterator & Rice::Hash::Iterator:: operator++() { // Ensure we're within the range if(current_index_ < hash_keys().size()) { current_index_++; } return *this; } template inline Rice::Hash::Iterator Rice::Hash::Iterator:: operator++(int) { Iterator copy(*this); ++(*this); return copy; } template inline Value_T Rice::Hash::Iterator:: operator*() { return Value_T(hash_, current_key()); } template inline Value_T * Rice::Hash::Iterator:: operator->() { Entry tmp(hash_, current_key()); this->tmp_.swap(tmp); return &tmp_; } template inline bool Rice::Hash::Iterator:: operator==(Iterator const & rhs) const { return hash_.value() == rhs.hash_.value() && current_index_ == rhs.current_index_; } template inline bool Rice::Hash::Iterator:: operator!=(Iterator const & rhs) const { return !(*this == rhs); } template inline void Rice::Hash::Iterator:: swap(Iterator& iterator) { using namespace std; hash_.swap(iterator.hash_); swap(keys_, iterator.keys_); swap(current_index_, iterator.current_index_); } template inline Rice::Object Rice::Hash::Iterator:: current_key() { return hash_keys()[current_index_]; } template inline Rice::Array Rice::Hash::Iterator:: hash_keys() { if(NIL_P(keys_)) { keys_ = rb_funcall(hash_, rb_intern("keys"), 0, 0); } return Rice::Array(keys_); } inline Rice::Hash::iterator Rice::Hash:: begin() { return iterator(*this); } inline Rice::Hash::const_iterator Rice::Hash:: begin() const { return const_iterator(*this); } inline Rice::Hash::iterator Rice::Hash:: end() { return iterator(*this, size()); } inline Rice::Hash::const_iterator Rice::Hash:: end() const { return const_iterator(*this, size()); } inline bool Rice:: operator<( Hash::Entry const & lhs, Hash::Entry const & rhs) { Object lhs_key(lhs.key); Object rhs_key(rhs.key); if(lhs_key < rhs_key) { return true; } else if(lhs_key > rhs_key) { return false; } else if(Object(lhs.value.value()) < Object(rhs.value.value())) { return true; } else { return false; } } #endif // Rice__Hash__ipp_