Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

Iterator_Definer.hpp

00001 #ifndef Exc_Ruby__detail__Iterator_Definer__hpp_
00002 #define Exc_Ruby__detail__Iterator_Definer__hpp_
00003 
00004 #include "../rb_cpp_method_data.hpp"
00005 #include "../call_ruby_function.hpp"
00006 #include "../detail/ruby_hacks.hpp"
00007 
00008 namespace Exc_Ruby
00009 {
00010 
00011 namespace detail
00012 {
00013 
00014 template<typename Derived_T>
00015 class Iterator_Definer
00016 {
00017 public:
00018   virtual ~Iterator_Definer()
00019   {
00020   }
00021 
00022   class Iterator
00023   {
00024   public:
00025     virtual ~Iterator() { }
00026 
00027     virtual VALUE call_impl(VALUE self) = 0;
00028 
00029     static VALUE call(VALUE self)
00030     {
00031       void * data = rb_cpp_method_data();
00032       Iterator * iterator = static_cast<Iterator *>(data);
00033       return iterator->call_impl(self);
00034     }
00035   };
00036 
00037   template<typename T, typename Iterator_T>
00038   class Iterator_Impl
00039     : public Iterator
00040   {
00041   public:
00042     Iterator_Impl(
00043         Iterator_T (T::*begin)(),
00044         Iterator_T (T::*end)())
00045       : begin_(begin)
00046       , end_(end)
00047     {
00048     }
00049 
00050     virtual VALUE call_impl(VALUE self)
00051     {
00052       // TODO: Optimize this by not using call_ruby_function every
00053       // iteration.
00054       Ruby_Reference<T> obj(self);
00055       Iterator_T it = obj->begin();
00056       Iterator_T end = obj->end();
00057       for(; it != end; ++it)
00058       {
00059         call_ruby_function(rb_yield, to_ruby(*it));
00060       }
00061       return self;
00062     }
00063 
00064   private:
00065     Iterator_T (T::*begin_)();
00066     Iterator_T (T::*end_)();
00067   };
00068 
00069   template<typename T, typename Iterator_T>
00070   Derived_T & define_iterator(
00071       char const * name,
00072       Iterator_T (T::*begin)(),
00073       Iterator_T (T::*end)())
00074   {
00075     Derived_T & self = static_cast<Derived_T &>(*this);
00076     // TODO: memory leak!!!!!!!
00077     Iterator * iterator = new Iterator_Impl<T, Iterator_T>(begin, end);
00078     rb_cpp_define_method_with_data(
00079         static_cast<VALUE>(self),
00080         name,
00081         (RUBY_METHOD_FUNC)iterator->call,
00082         0,
00083         iterator);
00084     return self;
00085   }
00086 };
00087 
00088 } // namespac edetail
00089 
00090 } // namespace Exc_Ruby
00091 
00092 #endif // Exc_Ruby__detail__Iterator_Definer__hpp_
00093 

Generated on Sat Jan 1 12:02:19 2005 for Exceptional Ruby by doxygen 1.3.6