#ifndef Rice__Hash__hpp_ #define Rice__Hash__hpp_ #include "Builtin_Object_defn.hpp" #include "to_from_ruby_defn.hpp" #include "detail/ruby.hpp" #include "detail/st.hpp" #include "detail/traits.hpp" #include namespace Rice { //! A wrapper for the ruby Hash class. //! This class provides a C++-style interface to ruby's Hash class and //! its associated rb_hash_* functions. //! Example: //! \code //! Hash h; //! h[42] = String("foo"); //! h[10] = String("bar"); //! std::cout << String(h[42]) << std::endl; //! \endcode class Hash : public Builtin_Object { public: //! Construct a new hash. Hash(); //! Wrap an existing hash. /*! \param v the hash to wrap. */ Hash(Object v); //! Return the number of elements in the hash. size_t size() const; private: //! A helper class so hash[key]=value can work. class Proxy; public: //! Get the value for the given key. /*! \param key the key whose value should be retrieved from the hash. * \return the value associated with the given key. */ template Proxy const operator[](Key_T const & key) const; //! Get the value for the given key. /*! \param key the key whose value should be retrieved from the hash. * \return the value associated with the given key. */ template Proxy operator[](Key_T const & key); //! Get the value for the given key /*! The returned value is converted to the type given by Value_T. * \param key the key whose value should be retrieved from the hash. * \return the value associated with the given key, converted to C++ * type Value_T. */ template Value_T get(Key_T const & key); //! A helper class for dereferencing iterators class Entry; //! A helper class for implementing iterators for a Hash. template class Iterator; public: //! An iterator. typedef Iterator iterator; //! A const iterator. typedef Iterator const_iterator; public: //! Return an iterator to the beginning of the hash. iterator begin(); //! Return a const iterator to the beginning of the hash. const_iterator begin() const; //! Return an iterator to the end of the hash. iterator end(); //! Return a const to the end of the hash. const_iterator end() const; }; //! A helper class so hash[key]=value can work. class Hash::Proxy { public: //! Construct a new Proxy. Proxy(Hash hash, Object key); //! Implicit conversion to Object. operator Object() const; //! Explicit conversion to VALUE. VALUE value() const; //! Assignment operator. template Object operator=(T const & value); void swap(Proxy & proxy); private: Hash hash_; Object key_; }; //! A helper class for dereferencing iterators /*! This class is intended to look similar to an std::pair. */ class Hash::Entry { public: //! Construct a new Entry. Entry(Hash hash, Object key); //! Copy constructor. Entry(Entry const & entry); Object const key; //!< The key Object const & first; //!< An alias for the key Proxy value; //!< The value Proxy & second; //!< An alias for the value Entry & operator=(Entry const & rhs); void swap(Entry & entry); friend bool operator<(Entry const & lhs, Entry const & rhs); }; bool operator<(Hash::Entry const & lhs, Hash::Entry const & rhs); //! A helper class for implementing iterators for a Hash. template class Hash::Iterator : public std::iterator< std::input_iterator_tag, Value_T> { public: //! Construct a new Iterator. Iterator(Hash_Ref_T hash, st_data_t bin, st_table_entry * ptr); //! Copy construct an Iterator. Iterator(Iterator const & iterator); //! Construct an Iterator from another Iterator of a different const //! qualification. template Iterator(Iterator_T const & iterator); //! Assignment operator. Iterator & operator=(Iterator const & rhs); //! Preincrement operator. Iterator & operator++(); //! Postincrement operator. Iterator operator++(int); //! Dereference operator. Value_T operator*(); //! Dereference operator. Value_T * operator->(); //! Equality operator. bool operator==(Iterator const & rhs) const; //! Inequality operator. bool operator!=(Iterator const & rhs) const; template friend class Hash::Iterator; //! Swap with another iterator of the same type. void swap(Iterator & iterator); private: Hash hash_; st_table * tbl_; #if RICE__RUBY_VERSION_CODE >= 190 st_index_t bin_; #else int bin_; #endif st_table_entry * ptr_; mutable typename detail::remove_const::Type tmp_; }; } // namespace Rice #include "Hash.ipp" #endif // Rice__Hash__hpp_