00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00066 #ifndef RC_DRIVER_OBJECT_H_
00067 #define RC_DRIVER_OBJECT_H_
00068
00069 #include <vector>
00070 #include <systemc.h>
00071
00072 #include <boost/bind.hpp>
00073 #include <boost/function.hpp>
00074 #include <boost/utility/addressof.hpp>
00075 #include <boost/type_traits/add_const.hpp>
00076 #include <boost/type_traits/remove_reference.hpp>
00077 #include <boost/type_traits/is_reference.hpp>
00078 #include <boost/type_traits/is_void.hpp>
00079
00080 #include "ReChannel/util/rc_throwable.h"
00081
00082 namespace ReChannel {
00083
00084 namespace internals {
00085 namespace driver_object {
00086
00090 template<class R, bool IS_REF = boost::is_reference<R>::value>
00091 class retval;
00092
00096 template<class R>
00097 class copy_retval;
00098
00102 class nb_driver_access_call;
00103
00107 template<class R>
00108 class driver_access_call;
00109
00110 }
00111 }
00112
00125 class rc_driver_object_base
00126 {
00130 friend class internals::driver_object::nb_driver_access_call;
00134 template<class R>
00135 friend class internals::driver_object::driver_access_call;
00136
00137 protected:
00141 struct write_call;
00147 typedef boost::function<void (void)> call_type;
00151 typedef std::vector<write_call> write_call_vector;
00155 typedef std::vector<write_call>::iterator write_call_iterator;
00156
00157 protected:
00159 rc_driver_object_base();
00160
00162 virtual ~rc_driver_object_base();
00163
00164 protected:
00168 virtual void writer_method_proc();
00169
00173 virtual void writer_thread_proc();
00174
00187 static void safe_event_notify(sc_event& e);
00188
00189 private:
00191 static void s_writer_method_proc();
00193 static sc_process_handle s_create_method_process();
00194
00195 protected:
00199 sc_process_handle m_hproc;
00203 write_call_vector* m_write_call_vector;
00210 sc_event* m_pending_write_event;
00217 bool m_pending_write_event_notified_flag;
00224 bool* m_pending_write_event_notified;
00225
00226 protected:
00227
00232 static sc_process_handle s_hproc;
00237 static write_call_vector s_write_call_vector;
00242 static sc_event s_pending_write_event;
00247 static bool s_pending_write_event_notified_flag;
00248
00249 protected:
00256 struct write_call
00257 {
00258 inline write_call(call_type call_);
00259 inline write_call(
00260 call_type call_, sc_event* write_done_event);
00261 inline write_call(
00262 call_type call_, sc_event* write_done_event,
00263 rc_throwable** throw_dest);
00264
00268 call_type m_call;
00277 sc_event* m_write_done_event;
00287 rc_throwable** m_throw_dest;
00288 };
00289
00290 private:
00291
00293 rc_driver_object_base(const rc_driver_object_base& dobj);
00295 rc_driver_object_base& operator=(const rc_driver_object_base& dobj);
00296 };
00297
00298 template<class IF, bool IS_THREAD> class rc_driver_object_b;
00299
00325 template<class IF>
00326 class rc_driver_object_b<IF, false>
00327 : public rc_driver_object_base
00328 {
00329 protected:
00330
00331 class driver_access;
00332 typedef rc_driver_object_b<IF, false> this_type;
00333 typedef rc_driver_object_base base_type;
00334
00335 typedef base_type::write_call write_call;
00336 typedef base_type::call_type call_type;
00337 typedef base_type::write_call_vector write_call_vector;
00338 typedef base_type::write_call_iterator write_call_iterator;
00339
00340 public:
00347 rc_driver_object_b(IF& channel);
00348
00352 IF& get_channel()
00353 { return *p_channel; }
00358 void set_channel(IF& channel)
00359 { p_channel = &channel; }
00360
00365 bool has_written() const
00366 { return m_write_call_vector->empty(); }
00367
00375 void cancel()
00376 {
00377 # if !defined(RC_USE_SHARED_METHOD_DRIVER)
00378 m_write_call_vector->clear();
00379 # endif
00380 }
00381
00382 private:
00386 IF* p_channel;
00387
00388 public:
00392 driver_access access;
00393
00394 private:
00395
00397 rc_driver_object_b(const this_type& dobj);
00399 this_type& operator=(const this_type& dobj);
00400 };
00401
00425 template<class IF>
00426 class rc_driver_object_b<IF, true>
00427 : public rc_driver_object_base
00428 {
00429 protected:
00430
00431 typedef rc_driver_object_b<IF, true> this_type;
00432 typedef rc_driver_object_base base_type;
00433
00434 typedef base_type::write_call write_call;
00435 typedef base_type::call_type call_type;
00436 typedef base_type::write_call_vector write_call_vector;
00437 typedef base_type::write_call_iterator write_call_iterator;
00438
00439 public:
00440 class driver_access;
00441
00442 public:
00449 rc_driver_object_b(IF& channel);
00450
00454 IF& get_channel()
00455 { return *p_channel; }
00460 void set_channel(IF& channel)
00461 { p_channel = &channel; }
00462
00467 bool has_written() const
00468 { return m_write_call_vector->empty(); }
00472 void cancel()
00473 { m_write_call_vector->clear(); }
00474
00475 private:
00479 IF* p_channel;
00480
00481 public:
00485 driver_access access;
00486
00487 private:
00488
00490 rc_driver_object_b(const this_type& dobj);
00492 this_type& operator=(const this_type& dobj);
00493 };
00494
00500 template<class IF>
00501 class rc_driver_object
00502 : public rc_driver_object_b<IF, true>
00503 {
00504 public:
00505
00506 typedef rc_driver_object<IF> this_type;
00507 typedef rc_driver_object_b<IF, true> base_type;
00508 typedef typename base_type::driver_access driver_access;
00509 public:
00516 rc_driver_object(IF& channel)
00517 : base_type(channel)
00518 { }
00519 };
00520
00526 template<class IF>
00527 class rc_nb_driver_object
00528 : public rc_driver_object_b<IF, false>
00529 {
00530 public:
00531
00532 typedef rc_nb_driver_object<IF> this_type;
00533 typedef rc_driver_object_b<IF, false> base_type;
00534 typedef typename base_type::driver_access driver_access;
00535 public:
00542 rc_nb_driver_object(IF& channel)
00543 : base_type(channel)
00544 { }
00545 };
00546
00547
00548
00549 inline rc_driver_object_base::write_call::write_call(
00550 rc_driver_object_base::call_type call_)
00551 : m_call(call_), m_write_done_event(NULL), m_throw_dest(NULL)
00552 { }
00553
00554 inline rc_driver_object_base::write_call::write_call(
00555 rc_driver_object_base::call_type call_,
00556 sc_event* write_done_event)
00557 : m_call(call_), m_write_done_event(write_done_event),
00558 m_throw_dest(NULL)
00559 { }
00560
00561 inline rc_driver_object_base::write_call::write_call(
00562 rc_driver_object_base::call_type call_,
00563 sc_event* write_done_event, rc_throwable** throw_dest)
00564 : m_call(call_), m_write_done_event(write_done_event),
00565 m_throw_dest(throw_dest)
00566 { }
00567
00568
00569
00570 template<class IF>
00571 rc_driver_object_b<IF, false>::rc_driver_object_b(IF& channel)
00572 : base_type(), p_channel(&channel), access(*this)
00573 {
00574 #if !defined(RC_USE_SHARED_METHOD_DRIVER)
00575
00576 std::auto_ptr<write_call_vector> wc_vector(new write_call_vector());
00577 std::auto_ptr<sc_event> pw_event(new sc_event());
00578 m_write_call_vector = wc_vector.get();
00579 m_pending_write_event = pw_event.get();
00580 m_pending_write_event_notified = &m_pending_write_event_notified_flag;
00581 sc_spawn_options opt;
00582 opt.set_sensitivity(m_pending_write_event);
00583 opt.dont_initialize();
00584 opt.spawn_method();
00585 m_hproc = sc_spawn(
00586 sc_bind(&this_type::writer_method_proc, this),
00587 sc_gen_unique_name("_rc_nb_driver_object_proc"),
00588 &opt);
00589 wc_vector.release();
00590 pw_event.release();
00591 #endif // !defined(RC_USE_SHARED_METHOD_DRIVER)
00592 }
00593
00594 template<class IF>
00595 rc_driver_object_b<IF, true>::rc_driver_object_b(IF& channel)
00596 : base_type(), p_channel(&channel), access(*this)
00597 {
00598
00599 std::auto_ptr<write_call_vector> wc_vector(new write_call_vector());
00600 std::auto_ptr<sc_event> pw_event(new sc_event());
00601 m_write_call_vector = wc_vector.get();
00602 m_pending_write_event = pw_event.get();
00603 m_pending_write_event_notified = &m_pending_write_event_notified_flag;
00604 sc_spawn_options opt;
00605 opt.set_sensitivity(m_pending_write_event);
00606 opt.dont_initialize();
00607 m_hproc = sc_spawn(
00608 sc_bind(&this_type::writer_thread_proc, this),
00609 sc_gen_unique_name("_rc_driver_object_proc"), &opt);
00610 wc_vector.release();
00611 pw_event.release();
00612 }
00613
00614
00615
00616
00617 template<class IF>
00618 class rc_driver_object_b<IF, false>::driver_access
00619 {
00620 friend class rc_driver_object_b<IF, false>;
00621
00622 protected:
00623 typedef rc_driver_object_b<IF, false> driver_object_type;
00624 typedef typename internals::driver_object::nb_driver_access_call
00625 nb_driver_access_call;
00626
00627 public:
00628
00629 template<class IF_>
00630 inline void call(void (IF_::*method)()) const
00631 {
00632 nb_driver_access_call()(
00633 dobj, boost::bind(method, dobj.p_channel));
00634 }
00635
00636 template<class IF_>
00637 inline void call(void (IF_::*method)() const) const
00638 {
00639 nb_driver_access_call()(
00640 dobj, boost::bind(method, dobj.p_channel));
00641 }
00642
00643 template<class A1, class A1_, class IF_>
00644 inline void call(void (IF_::*method)(A1_), A1 a1) const
00645 {
00646 nb_driver_access_call()(
00647 dobj, boost::bind(method, dobj.p_channel, a1));
00648 }
00649
00650 template<class A1, class A1_, class IF_>
00651 inline void call(void (IF_::*method)(A1_) const, A1 a1) const
00652 {
00653 nb_driver_access_call()(
00654 dobj, boost::bind(method, dobj.p_channel, a1));
00655 }
00656
00657 template<class A1, class A2, class A1_, class A2_, class IF_>
00658 inline void call(void (IF_::*method)(A1_, A2_), A1 a1, A2 a2) const
00659 {
00660 nb_driver_access_call()(
00661 dobj, boost::bind(method, dobj.p_channel, a1, a2));
00662 }
00663
00664 template<class A1, class A2, class A1_, class A2_, class IF_>
00665 inline void call(void (IF_::*method)(A1_, A2_) const,
00666 A1 a1, A2 a2) const
00667 {
00668 nb_driver_access_call()(
00669 dobj, boost::bind(method, dobj.p_channel, a1, a2));
00670 }
00671
00672 template<class A1, class A2, class A3,
00673 class A1_, class A2_, class A3_, class IF_>
00674 inline void call(
00675 void (IF_::*method)(A1_, A2_, A3_), A1 a1, A2 a2, A3 a3) const
00676 {
00677 nb_driver_access_call()(
00678 dobj, boost::bind(method, dobj.p_channel, a1, a2, a3));
00679 }
00680
00681 template<class A1, class A2, class A3,
00682 class A1_, class A2_, class A3_, class IF_>
00683 inline void call(
00684 void (IF_::*method)(A1_, A2_, A3_) const,
00685 A1 a1, A2 a2, A3 a3) const
00686 {
00687 nb_driver_access_call()(
00688 dobj, boost::bind(method, dobj.p_channel, a1, a2, a3));
00689 }
00690
00691 template<class A1, class A2, class A3, class A4,
00692 class A1_, class A2_, class A3_, class A4_, class IF_>
00693 inline void call(
00694 void (IF_::*method)(A1_, A2_, A3_, A4_),
00695 A1 a1, A2 a2, A3 a3, A4 a4) const
00696 {
00697 nb_driver_access_call()(
00698 dobj, boost::bind(method, dobj.p_channel,
00699 a1, a2, a3, a4));
00700 }
00701
00702 template<class A1, class A2, class A3, class A4,
00703 class A1_, class A2_, class A3_, class A4_, class IF_>
00704 inline void call(
00705 void (IF_::*method)(A1_, A2_, A3_, A4_) const,
00706 A1 a1, A2 a2, A3 a3, A4 a4) const
00707 {
00708 nb_driver_access_call()(
00709 dobj, boost::bind(method, dobj.p_channel,
00710 a1, a2, a3, a4));
00711 }
00712
00713 template<class A1, class A2, class A3, class A4, class A5,
00714 class A1_, class A2_, class A3_, class A4_, class A5_, class IF_>
00715 inline void call(
00716 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_),
00717 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
00718 {
00719 nb_driver_access_call()(
00720 dobj, boost::bind(method, dobj.p_channel,
00721 a1, a2, a3, a4, a5));
00722 }
00723
00724 template<class A1, class A2, class A3, class A4, class A5,
00725 class A1_, class A2_, class A3_, class A4_, class A5_, class IF_>
00726 inline void call(
00727 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_) const,
00728 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
00729 {
00730 nb_driver_access_call()(
00731 dobj, boost::bind(method, dobj.p_channel,
00732 a1, a2, a3, a4, a5));
00733 }
00734
00735 template<class A1, class A2, class A3, class A4, class A5, class A6,
00736 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00737 class IF_>
00738 inline void call(
00739 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_),
00740 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
00741 {
00742 nb_driver_access_call()(
00743 dobj, boost::bind(method, dobj.p_channel,
00744 a1, a2, a3, a4, a5, a6));
00745 }
00746
00747 template<class A1, class A2, class A3, class A4, class A5, class A6,
00748 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00749 class IF_>
00750 inline void call(
00751 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_) const,
00752 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
00753 {
00754 nb_driver_access_call()(
00755 dobj, boost::bind(method, dobj.p_channel,
00756 a1, a2, a3, a4, a5, a6));
00757 }
00758
00759 template<class A1, class A2, class A3, class A4, class A5, class A6,
00760 class A7,
00761 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00762 class A7_, class IF_>
00763 inline void call(
00764 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_),
00765 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
00766 {
00767 nb_driver_access_call()(
00768 dobj, boost::bind(method, dobj.p_channel,
00769 a1, a2, a3, a4, a5, a6, a7));
00770 }
00771
00772 template<class A1, class A2, class A3, class A4, class A5,
00773 class A6, class A7,
00774 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00775 class A7_, class IF_>
00776 inline void call(
00777 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_) const,
00778 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
00779 {
00780 nb_driver_access_call()(
00781 dobj, boost::bind(method, dobj.p_channel,
00782 a1, a2, a3, a4, a5, a6, a7));
00783 }
00784
00785 template<class A1, class A2, class A3, class A4, class A5, class A6,
00786 class A7, class A8,
00787 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00788 class A7_, class A8_, class IF_>
00789 inline void call(
00790 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_),
00791 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
00792 {
00793 nb_driver_access_call()(
00794 dobj, boost::bind(method, dobj.p_channel,
00795 a1, a2, a3, a4, a5, a6, a7, a8));
00796 }
00797
00798 template<class A1, class A2, class A3, class A4, class A5, class A6,
00799 class A7, class A8,
00800 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00801 class A7_, class A8_, class IF_>
00802 inline void call(
00803 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_) const,
00804 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
00805 {
00806 nb_driver_access_call()(
00807 dobj, boost::bind(method, dobj.p_channel,
00808 a1, a2, a3, a4, a5, a6, a7, a8));
00809 }
00810
00811 template<class A1, class A2, class A3, class A4, class A5, class A6,
00812 class A7, class A8, class A9,
00813 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00814 class A7_, class A8_, class A9_, class IF_>
00815 inline void call(
00816 void (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_),
00817 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
00818 A7 a7, A8 a8, A9 a9) const
00819 {
00820 nb_driver_access_call()(
00821 dobj, boost::bind(method, dobj.p_channel,
00822 a1, a2, a3, a4, a5, a6, a7, a8, a9));
00823 }
00824
00825 template<class A1, class A2, class A3, class A4, class A5, class A6,
00826 class A7, class A8, class A9,
00827 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00828 class A7_, class A8_, class A9_, class IF_>
00829 inline void call(
00830 void (IF_::*method)(
00831 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_) const,
00832 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
00833 A7 a7, A8 a8, A9 a9) const
00834 {
00835 nb_driver_access_call()(
00836 dobj, boost::bind(method, dobj.p_channel,
00837 a1, a2, a3, a4, a5, a6, a7, a8, a9));
00838 }
00839
00840 template<class A1, class A2, class A3, class A4, class A5, class A6,
00841 class A7, class A8, class A9, class A10,
00842 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00843 class A7_, class A8_, class A9_, class A10_, class IF_>
00844 inline void call(
00845 void (IF_::*method)(
00846 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_, A10_),
00847 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
00848 A7 a7, A8 a8, A9 a9, A10 a10) const
00849 {
00850 nb_driver_access_call()(
00851 dobj, boost::bind(method, dobj.p_channel,
00852 a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
00853 }
00854
00855 template<class A1, class A2, class A3, class A4, class A5, class A6,
00856 class A7, class A8, class A9, class A10,
00857 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
00858 class A7_, class A8_, class A9_, class A10_, class IF_>
00859 inline void call(
00860 void (IF_::*method)(
00861 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_, A10_) const,
00862 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
00863 A7 a7, A8 a8, A9 a9, A10 a10) const
00864 {
00865 nb_driver_access_call()(
00866 dobj, boost::bind(method, dobj.p_channel,
00867 a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
00868 }
00869
00870 private:
00871 driver_access(driver_object_type& dobj_)
00872 : dobj(dobj_)
00873 { }
00874
00875 private:
00876 driver_object_type& dobj;
00877
00878 private:
00879
00880 driver_access(const driver_access& access);
00881 driver_access& operator=(const driver_access& access);
00882 };
00883
00884
00885 template<class IF>
00886 class rc_driver_object_b<IF, true>::driver_access
00887 {
00888 friend class rc_driver_object_b<IF, true>;
00889
00890 protected:
00891 typedef rc_driver_object_b<IF, true> driver_object_type;
00892
00893 public:
00894
00895
00896 template<class R, class IF_>
00897 inline R call(R (IF_::*method)()) const
00898 {
00899 return typename internals::driver_object::driver_access_call<R>()(
00900 dobj, boost::bind(method, dobj.p_channel));
00901 }
00902
00903 template<class R, class IF_>
00904 inline R call(R (IF_::*method)() const) const
00905 {
00906 return typename internals::driver_object::driver_access_call<R>()(
00907 dobj, boost::bind(method, dobj.p_channel));
00908 }
00909
00910 template<class R, class A1, class A1_, class IF_>
00911 inline R call(R (IF_::*method)(A1_), A1 a1) const
00912 {
00913 return typename internals::driver_object::driver_access_call<R>()(
00914 dobj, boost::bind(method, dobj.p_channel, a1));
00915 }
00916
00917 template<class R, class A1, class A1_, class IF_>
00918 inline R call(R (IF_::*method)(A1_) const, A1 a1) const
00919 {
00920 return typename internals::driver_object::driver_access_call<R>()(
00921 dobj, boost::bind(method, dobj.p_channel, a1));
00922 }
00923
00924 template<class R, class A1, class A2, class A1_, class A2_, class IF_>
00925 inline R call(R (IF_::*method)(A1_, A2_), A1 a1, A2 a2) const
00926 {
00927 return typename internals::driver_object::driver_access_call<R>()(
00928 dobj, boost::bind(
00929 method, dobj.p_channel, a1, a2));
00930 }
00931
00932 template<class R, class A1, class A2, class A1_, class A2_, class IF_>
00933 inline R call(R (IF_::*method)(A1_, A2_) const, A1 a1, A2 a2) const
00934 {
00935 return typename internals::driver_object::driver_access_call<R>()(
00936 dobj, boost::bind(
00937 method, dobj.p_channel, a1, a2));
00938 }
00939
00940 template<class R, class A1, class A2, class A3,
00941 class A1_, class A2_, class A3_, class IF_>
00942 inline R call(
00943 R (IF_::*method)(A1_, A2_, A3_), A1 a1, A2 a2, A3 a3) const
00944 {
00945 return typename internals::driver_object::driver_access_call<R>()(
00946 dobj, boost::bind(
00947 method, dobj.p_channel, a1, a2, a3));
00948 }
00949
00950 template<class R, class A1, class A2, class A3,
00951 class A1_, class A2_, class A3_, class IF_>
00952 inline R call(
00953 R (IF_::*method)(A1_, A2_, A3_) const, A1 a1, A2 a2, A3 a3) const
00954 {
00955 return typename internals::driver_object::driver_access_call<R>()(
00956 dobj, boost::bind(
00957 method, dobj.p_channel, a1, a2, a3));
00958 }
00959
00960 template<class R, class A1, class A2, class A3, class A4,
00961 class A1_, class A2_, class A3_, class A4_, class IF_>
00962 inline R call(
00963 R (IF_::*method)(A1_, A2_, A3_, A4_),
00964 A1 a1, A2 a2, A3 a3, A4 a4) const
00965 {
00966 return typename internals::driver_object::driver_access_call<R>()(
00967 dobj, boost::bind(
00968 method, dobj.p_channel, a1, a2, a3, a4));
00969 }
00970
00971 template<class R, class A1, class A2, class A3, class A4,
00972 class A1_, class A2_, class A3_, class A4_, class IF_>
00973 inline R call(
00974 R (IF_::*method)(A1_, A2_, A3_, A4_) const,
00975 A1 a1, A2 a2, A3 a3, A4 a4) const
00976 {
00977 return typename internals::driver_object::driver_access_call<R>()(
00978 dobj, boost::bind(
00979 method, dobj.p_channel, a1, a2, a3, a4));
00980 }
00981
00982 template<class R, class A1, class A2, class A3, class A4, class A5,
00983 class A1_, class A2_, class A3_, class A4_, class A5_, class IF_>
00984 inline R call(
00985 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_),
00986 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
00987 {
00988 return typename internals::driver_object::driver_access_call<R>()(
00989 dobj, boost::bind(
00990 method, dobj.p_channel, a1, a2, a3, a4, a5));
00991 }
00992
00993 template<class R, class A1, class A2, class A3, class A4, class A5,
00994 class A1_, class A2_, class A3_, class A4_, class A5_, class IF_>
00995 inline R call(
00996 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_) const,
00997 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
00998 {
00999 return typename internals::driver_object::driver_access_call<R>()(
01000 dobj, boost::bind(
01001 method, dobj.p_channel, a1, a2, a3, a4, a5));
01002 }
01003
01004 template<class R,
01005 class A1, class A2, class A3, class A4, class A5, class A6,
01006 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01007 class IF_>
01008 inline R call(
01009 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_),
01010 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
01011 {
01012 return typename internals::driver_object::driver_access_call<R>()(
01013 dobj, boost::bind(
01014 method, dobj.p_channel, a1, a2, a3, a4, a5, a6));
01015 }
01016
01017 template<class R,
01018 class A1, class A2, class A3, class A4, class A5, class A6,
01019 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01020 class IF_>
01021 inline R call(
01022 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_) const,
01023 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
01024 {
01025 return typename internals::driver_object::driver_access_call<R>()(
01026 dobj, boost::bind(
01027 method, dobj.p_channel, a1, a2, a3, a4, a5, a6));
01028 }
01029
01030 template<class R,
01031 class A1, class A2, class A3, class A4, class A5, class A6,
01032 class A7,
01033 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01034 class A7_, class IF_>
01035 inline R call(
01036 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_),
01037 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
01038 {
01039 return typename internals::driver_object::driver_access_call<R>()(
01040 dobj, boost::bind(
01041 method, dobj.p_channel, a1, a2, a3, a4, a5, a6, a7));
01042 }
01043
01044 template<class R,
01045 class A1, class A2, class A3, class A4, class A5, class A6,
01046 class A7,
01047 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01048 class A7_, class IF_>
01049 inline R call(
01050 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_) const,
01051 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
01052 {
01053 return typename internals::driver_object::driver_access_call<R>()(
01054 dobj, boost::bind(
01055 method, dobj.p_channel, a1, a2, a3, a4, a5, a6, a7));
01056 }
01057
01058 template<class R,
01059 class A1, class A2, class A3, class A4, class A5, class A6,
01060 class A7, class A8,
01061 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01062 class A7_, class A8_, class IF_>
01063 inline R call(
01064 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_),
01065 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
01066 {
01067 return typename internals::driver_object::driver_access_call<R>()(
01068 dobj, boost::bind(
01069 method, dobj.p_channel, a1, a2, a3, a4, a5, a6, a7, a8));
01070 }
01071
01072 template<class R,
01073 class A1, class A2, class A3, class A4, class A5, class A6,
01074 class A7, class A8,
01075 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01076 class A7_, class A8_, class IF_>
01077 inline R call(
01078 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_) const,
01079 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
01080 {
01081 return typename internals::driver_object::driver_access_call<R>()(
01082 dobj, boost::bind(
01083 method, dobj.p_channel, a1, a2, a3, a4, a5, a6, a7, a8));
01084 }
01085
01086 template<class R,
01087 class A1, class A2, class A3, class A4, class A5, class A6,
01088 class A7, class A8, class A9,
01089 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01090 class A7_, class A8_, class A9_, class IF_>
01091 inline R call(
01092 R (IF_::*method)(A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_),
01093 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
01094 const
01095 {
01096 return typename internals::driver_object::driver_access_call<R>()(
01097 dobj, boost::bind(
01098 method, dobj.p_channel,
01099 a1, a2, a3, a4, a5, a6, a7, a8, a9));
01100 }
01101
01102 template<class R,
01103 class A1, class A2, class A3, class A4, class A5, class A6,
01104 class A7, class A8, class A9,
01105 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01106 class A7_, class A8_, class A9_, class IF_>
01107 inline R call(
01108 R (IF_::*method)(
01109 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_) const,
01110 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
01111 const
01112 {
01113 return typename internals::driver_object::driver_access_call<R>()(
01114 dobj, boost::bind(
01115 method, dobj.p_channel,
01116 a1, a2, a3, a4, a5, a6, a7, a8, a9));
01117 }
01118
01119 template<class R,
01120 class A1, class A2, class A3, class A4, class A5, class A6,
01121 class A7, class A8, class A9, class A10,
01122 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01123 class A7_, class A8_, class A9_, class A10_, class IF_>
01124 inline R call(
01125 R (IF_::*method)(
01126 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_, A10_),
01127 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
01128 A7 a7, A8 a8, A9 a9, A10 a10) const
01129 {
01130 return typename internals::driver_object::driver_access_call<R>()(
01131 dobj, boost::bind(
01132 method, dobj.p_channel,
01133 a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
01134 }
01135
01136 template<class R,
01137 class A1, class A2, class A3, class A4, class A5, class A6,
01138 class A7, class A8, class A9, class A10,
01139 class A1_, class A2_, class A3_, class A4_, class A5_, class A6_,
01140 class A7_, class A8_, class A9_, class A10_, class IF_>
01141 inline R call(
01142 R (IF_::*method)(
01143 A1_, A2_, A3_, A4_, A5_, A6_, A7_, A8_, A9_, A10_) const,
01144 A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
01145 A7 a7, A8 a8, A9 a9, A10 a10) const
01146 {
01147 return typename internals::driver_object::driver_access_call<R>()(
01148 dobj, boost::bind(
01149 method, dobj.p_channel,
01150 a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
01151 }
01152
01153 private:
01154 driver_access(driver_object_type& dobj_)
01155 : dobj(dobj_)
01156 { }
01157
01158 private:
01159 driver_object_type& dobj;
01160
01161 private:
01162
01163 driver_access(const driver_access& access);
01164 driver_access& operator=(const driver_access& access);
01165 };
01166
01167 namespace internals {
01168 namespace driver_object {
01169
01175 template<class R>
01176 class copy_retval
01177 {
01178 public:
01179 typedef typename boost::add_const<R>::type src_type;
01180 typedef retval<R, boost::is_reference<R>::value> dest_type;
01181
01182 void operator()(src_type src, dest_type* dest) const
01183 { (*dest) = src; }
01184 };
01185
01191
01192 template<class R>
01193 class retval<R, false>
01194 {
01195 typedef retval<R, false> this_type;
01196 typedef typename boost::add_const<R>::type const_value_type;
01197
01198 public:
01199 inline retval() {}
01200 inline operator R() const { return value; }
01201 inline this_type& operator=(const_value_type new_value)
01202 {
01203 value = new_value;
01204 return *this;
01205 }
01206 private:
01207 R value;
01208 };
01209
01215
01216 template<class R>
01217 class retval<R, true>
01218 {
01219 typedef retval<R, true> this_type;
01220 typedef typename boost::add_const<R>::type const_value_type;
01221 typedef typename boost::remove_reference<R>::type* value_ptr_type;
01222 public:
01223 inline retval() : value_ptr(NULL) {}
01224 inline operator R() const { return *value_ptr; }
01225 inline this_type& operator=(const_value_type new_value)
01226 {
01227 value_ptr = boost::addressof(new_value);
01228 return *this;
01229 }
01230 private:
01231 value_ptr_type value_ptr;
01232 };
01233
01237 class nb_driver_access_call
01238 {
01239 private:
01240 typedef ::ReChannel::rc_driver_object_base
01241 driver_object_type;
01242 typedef driver_object_type::call_type call_type;
01243 typedef driver_object_type::write_call write_call;
01244
01245 public:
01246 inline nb_driver_access_call() {}
01247
01248
01249 void operator()(driver_object_type& dobj, call_type call_obj);
01250 };
01251
01257
01258 template<class R>
01259 class driver_access_call
01260 {
01261 private:
01262 typedef typename ::ReChannel::rc_driver_object_base
01263 driver_object_type;
01264 typedef typename driver_object_type::write_call
01265 write_call;
01266 typedef typename internals::driver_object::retval<R>
01267 retval;
01268 typedef typename internals::driver_object::copy_retval<R>
01269 copy_retval;
01270
01271 public:
01272 inline driver_access_call() {}
01273
01274
01275 template<class BIND_OBJ>
01276 R operator()(driver_object_type& dobj, BIND_OBJ call_obj) const;
01277 };
01278
01279 template<class R>
01280 template<class BIND_OBJ>
01281 R driver_access_call<R>::operator()(
01282 driver_object_type& dobj, BIND_OBJ call_obj) const
01283 {
01284
01285 retval ret;
01286
01287 sc_event write_done_event;
01288
01289 rc_throwable* thrown_obj = NULL;
01290
01291
01292 dobj.m_write_call_vector->push_back(
01293 write_call(
01294 boost::bind(
01295 copy_retval(), call_obj, &ret),
01296 &write_done_event, &thrown_obj));
01297
01298
01299 if (!*dobj.m_pending_write_event_notified) {
01300 *dobj.m_pending_write_event_notified = true;
01301 rc_driver_object_base::safe_event_notify(
01302 *dobj.m_pending_write_event);
01303 }
01304
01305 ::sc_core::wait(write_done_event);
01306
01307 if (thrown_obj != NULL) {
01308 ::ReChannel::rc_throw(thrown_obj);
01309 }
01310
01311
01312 return (R)ret;
01313 }
01314
01320
01321 template<>
01322 class driver_access_call<void>
01323 {
01324 private:
01325 typedef ::ReChannel::rc_driver_object_base
01326 driver_object_type;
01327 typedef driver_object_type::call_type call_type;
01328 typedef driver_object_type::write_call write_call;
01329
01330 public:
01331 inline driver_access_call() {}
01332
01333
01334 void operator()(driver_object_type& dobj, call_type call_obj) const;
01335 };
01336
01337 }
01338 }
01339
01340 }
01341
01342 #endif // RC_DRIVER_OBJECT_H_
01343
01344
01345
01346
01347