Zen
A cross-platform functional programming language

/home/renji/Data/projects/zenlang/sources/zbl/ztl.hpp

Go to the documentation of this file.
00001 
00007 #pragma once
00008 
00009 #include "zrt.hpp"
00010 
00012 namespace ztl {
00014 
00016     template <typename ReturnT>
00017     class ClosureT : public zbl::Closure {
00018     protected:
00021         inline ClosureT(){}
00022 
00023     private:
00027         inline ClosureT(const ClosureT& src) {unused(src);}
00028 
00029     public:
00033         inline ReturnT& getValue() {return *_val;}
00034 
00038         inline void setValue(const ReturnT& val) {_val.reset(new ReturnT(val));}
00039 
00040     private:
00042         z::scopedptr<ReturnT> _val;
00043     };
00044 
00046 
00048     template <typename ReturnT>
00049     class FunctionCallClosureT : public ClosureT<ReturnT> {
00050     };
00051 
00053 
00055     class SharedClosureT : public zbl::Closure {
00056     protected:
00059         inline SharedClosureT(){}
00060 
00061     private:
00065         inline SharedClosureT(const SharedClosureT& src) {unused(src);}
00066     };
00067 
00069 
00071     class LoopClosureT : public zbl::Closure {
00072     protected:
00075         inline LoopClosureT(){}
00076 
00077     private:
00081         inline LoopClosureT(const LoopClosureT& src) {unused(src);}
00082     };
00083 
00085 
00087     template <typename ReturnT>
00088     class ReturnClosureT : public ClosureT<ReturnT> {
00089     protected:
00092         inline ReturnClosureT(){}
00093     };
00094 
00096 
00098     template <typename ReturnT>
00099     class ContinuationT : public zbl::Continuation {
00100     public:
00101         typedef z::scopedptr<ContinuationT> Ptr;
00102     protected:
00105         inline ContinuationT() : Continuation(), _parent(0) {}
00106 
00110         inline ContinuationT(const ContinuationT& src) : Continuation(src), _parent(0) {}
00111 
00112     public:
00116         inline void setParent(ClosureT<ReturnT>& parent) {_parent = ptr(parent);}
00117 
00118     private:
00122         virtual void setParent(zbl::Closure* parent) {
00123             ClosureT<ReturnT>* p = dynamic_cast< ClosureT<ReturnT>* >(parent);
00124             assert(p);
00125             ref(this).setParent(ref(p));
00126         }
00127 
00128     public:
00132         inline ContinuationT<ReturnT>* cloneT() const {
00133             zbl::Continuation::Ptr continuation;
00134             clone(continuation);
00135             return dynamic_cast<ContinuationT<ReturnT>* >(continuation.take());
00136         }
00137 
00138 #ifdef TRACE_RUN
00139     private:
00143         virtual zbl::Closure* getParent() const {return _parent;}
00144 #endif
00145 
00146     public:
00150         inline void setReturn(const ReturnT& val) {
00151             if(_parent)
00152                 ref(_parent).setValue(val);
00153         }
00154 
00155     private:
00157         ClosureT<ReturnT>* _parent;
00158     };
00159 
00161 
00163     template <typename ReturnT>
00164     class ContinuationListT : public z::queue<ztl::ContinuationT<ReturnT>*> {
00165     public:
00168         inline ~ContinuationListT();
00169 
00170     public:
00174         inline void take(ContinuationListT<ReturnT>& src);
00175     };
00176 
00178 
00180     template <typename ReturnT>
00181     class RunContextT {
00182     public:
00185         inline RunContextT(zbl::Engine& engine) : _engine(engine) {}
00186 
00187     public:
00192         inline ContinuationT<ReturnT>& append(ContinuationT<ReturnT>* continuation) {
00193             _continuationList.append(continuation);
00194             return ref(continuation);
00195         }
00196 
00197     public:
00201         inline zbl::Engine& getEngine() {return _engine;}
00202 
00206         inline bool hasContinuation() {return (_continuationList.size() > 0);}
00207 
00211         inline void getContinuation(typename ztl::ContinuationT<ReturnT>::Ptr& continuation) {continuation.reset(_continuationList.deque());}
00212 
00213     private:
00215         zbl::Engine& _engine;
00216 
00218         ztl::ContinuationListT<ReturnT> _continuationList;
00219     };
00220 
00222 
00233     template <typename srcT, typename rtnT, typename ctxT, typename contT>
00234     inline void adaptFunction(contT& cont, typename srcT::Impl::RunCtx& src, ctxT& dstCtx) {
00235         while(src.hasContinuation()) {
00236             typename ztl::ContinuationT<rtnT>::Ptr childSeq;
00237             src.getContinuation(childSeq);
00238             z::scopedptr<contT> parentSeq(new contT(cont));
00239             childSeq->setParent(parentSeq->getFCall());
00240             parentSeq->setChild(childSeq.take());
00241             dstCtx.append(parentSeq.take());
00242         }
00243     }
00244 
00246 
00250     template <typename srcT, typename rtnT>
00251     inline void adaptClosure(typename srcT::Impl::RunCtx& src, zbl::RunContext& dstCtx) {
00252         while(src.hasContinuation()) {
00253             typename ztl::ContinuationT<rtnT>::Ptr childSeq;
00254             src.getContinuation(childSeq);
00255             dstCtx.append(childSeq.take());
00256         }
00257     }
00258 
00260 
00263     template <typename srcT, typename rtnT>
00264     inline void adaptNative(typename srcT::Impl::RunCtx& src) {
00265         zbl::RunContext rctx(src.getEngine());
00266         adaptClosure<srcT, rtnT>(src, rctx);
00267         src.getEngine().enque(rctx);
00268     }
00269 
00271 
00273     template <typename T, typename ImplT>
00274     class TestFactoryT : public zbl::TestFactory {
00275     private:
00278         class TcontinuationT : public ContinuationT<int> {
00279         private:
00282             class _C_test : public FunctionCallClosureT<typename T::Return> {
00283             public:
00286 
00287                 inline _C_test(const z::string& name) : _name(name) {}
00288 
00289             private:
00291                 zbl::Linker _runner;
00292 
00295                 virtual zbl::Runner& getRunner() {return _runner;}
00296 
00297 #ifdef TRACE_RUN
00298             private:
00302                 virtual void trace(z::stream& os) const {
00303                     os << "name=\"TestFactoryT::TcontinuationT::TClosure\", test=\"" << _name << "\"";
00304                 }
00305 #endif
00306 
00311                 virtual zbl::Closure::Action::T runClosureWithCtx(zbl::RunContext& _ctx) {
00312                     typename ImplT::RunCtx _pctx(_ctx.getEngine());
00313                     ImplT fcall;
00314                     typename T::Return rv = fcall.run(_pctx);
00315                     setValue(rv);
00316                     ztl::adaptClosure<T, typename T::Return>(_pctx, _ctx);
00317                     return zbl::Closure::Action::Next;
00318                 }
00319 
00320             public:
00322                 const z::string& _name;
00323             };
00324 
00325         private:
00328             class _C_rtn : public ReturnClosureT<int> {
00329             public:
00335                 inline _C_rtn(const z::string& name, zbl::TestResult& tr, _C_test& p_x) : _name(name), _tr(tr), x(p_x) {}
00336 
00337             private:
00339                 zbl::Linker _runner;
00340 
00343                 virtual zbl::Runner& getRunner() {return _runner;}
00344 
00345 #ifdef TRACE_RUN
00346             private:
00350                 virtual void trace(z::stream& os) const {
00351                     os << "name=\"TestFactoryT::TcontinuationT::RClosure\", test=\"" << _name << "\"";
00352                 }
00353 #endif
00354 
00359                 virtual Action::T runClosureWithCtx(zbl::RunContext& _ctx) {
00360                     unused(_ctx);
00361                     _tr.add(_name, x.getValue().passed);
00362                     return Action::Next;
00363                 }
00364             public:
00366                 const z::string& _name;
00367 
00369                 zbl::TestResult& _tr;
00370 
00372                 _C_test& x;
00373             };
00374 
00378             virtual void clone(zbl::Continuation::Ptr& continuation) const {
00379                 continuation.reset(new TcontinuationT(*this));
00380             }
00381 
00382         private:
00384             _C_test _test;
00385 
00387             _C_rtn  _rtn;
00388 
00389         private:
00392             inline void init() {_closureList << ptr(_test) << ptr(_rtn);}
00393 
00394         public:
00397             inline TcontinuationT(const z::string& name, zbl::TestResult& tr) : ContinuationT<int>(), _test(name), _rtn(name, tr, _test) {init();}
00398 
00402             inline TcontinuationT(const TcontinuationT& src) : ContinuationT<int>(src), _test(src._rtn._name), _rtn(src._rtn._name, src._rtn._tr, _test) {init();}
00403         };
00404 
00405     public:
00409         inline TestFactoryT(const z::string& name) : TestFactory(name) {}
00410 
00411     private:
00415         virtual zbl::Continuation* get() const {return new TcontinuationT(_name, ref(_tr));}
00416     };
00417 }
00418 
00420 template <typename rtnT>
00421 inline ztl::ContinuationListT<rtnT>::~ContinuationListT() {
00422     // The list should be empty at dtor time...
00423     if(ref(this).size() != 0) {
00424         throw z::exception(z::string::creator("Internal error: ContinuationListT should be empty in dtor").value());
00425     }
00426     // but delete any remaining ones in Release build.
00427     while(ref(this).size() > 0) {
00429     }
00430 }
00431 
00433 template <typename rtnT>
00434 inline void ztl::ContinuationListT<rtnT>::take(ContinuationListT<rtnT>& src) {
00435     while(src.size() > 0) {
00436         zbl::Continuation::Ptr ptr(src.deque());
00437         ref(this).append(ptr.take());
00438     }
00439 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines