libsesstype  2.0.0
Library for Session Types programming.
interruptible.h
00001 #ifndef SESSTYPE__NODE__INTERRUPTIBLE_H__
00002 #define SESSTYPE__NODE__INTERRUPTIBLE_H__
00003 
00004 #ifdef __cplusplus
00005 #include <algorithm>
00006 #include <string>
00007 #include <unordered_map>
00008 #endif
00009 
00010 #include "sesstype/msg.h"
00011 #include "sesstype/node.h"
00012 #include "sesstype/role.h"
00013 #include "sesstype/node/block.h"
00014 
00015 #ifdef __cplusplus
00016 namespace sesstype {
00017 #endif
00018 
00019 #ifdef __cplusplus
00020 
00023 template <class BaseNode, class RoleType, class MessageType, class VisitorType>
00024 class InterruptibleNodeTmpl : public BlockNodeTmpl<BaseNode, RoleType, MessageType, VisitorType> {
00025     std::string scope_;
00026     typename std::unordered_multimap<RoleType *, MessageType *> interrupts_;
00027     typename std::unordered_multimap<RoleType *, MessageType *> throws_;
00028     typename std::unordered_multimap<RoleType *, MessageType *> catches_;
00029 
00030   public:
00031     typedef typename std::unordered_multimap<RoleType *, MessageType *> InterruptType;
00032 
00034     InterruptibleNodeTmpl()
00035         : BlockNodeTmpl<BaseNode, RoleType, MessageType, VisitorType>(ST_NODE_INTERRUPTIBLE),
00036           scope_(), interrupts_(), throws_(), catches_() { }
00037 
00039     InterruptibleNodeTmpl(std::string scope)
00040         : BlockNodeTmpl<BaseNode, RoleType, MessageType, VisitorType>(ST_NODE_INTERRUPTIBLE),
00041           scope_(scope), interrupts_(), throws_(), catches_() { }
00042 
00043 
00045     InterruptibleNodeTmpl(const InterruptibleNodeTmpl &node)
00046         : BlockNodeTmpl<BaseNode, RoleType, MessageType, VisitorType>(node),
00047           scope_(node.scope_), interrupts_(), throws_(), catches_()
00048     {
00049         for (auto interrupt : node.interrupts_) {
00050             RoleType *role = interrupt.first->clone();
00051             MessageType *msg = interrupt.second->clone();
00052             add_interrupt(role, msg);
00053         }
00054         for (auto thr : node.throws_) {
00055             RoleType *role = thr.first->clone();
00056             MessageType *msg = thr.second->clone();
00057             add_throw(role, msg);
00058         }
00059         for (auto interrupt : node.catches_) {
00060             RoleType *role = interrupt.first->clone();
00061             MessageType *msg = interrupt.second->clone();
00062             add_catch(role, msg);
00063         }
00064     }
00065 
00067     ~InterruptibleNodeTmpl() override
00068     {
00069         for (auto interrupt : interrupts_) {
00070             delete interrupt.first;
00071             delete interrupt.second;
00072         }
00073         interrupts_.clear();
00074 
00075         for (auto thr : throws_) {
00076             delete thr.first;
00077             delete thr.second;
00078         }
00079         throws_.clear();
00080 
00081         for (auto cat : catches_) {
00082             delete cat.first;
00083             delete cat.second;
00084         }
00085         catches_.clear();
00086     }
00087 
00089     InterruptibleNodeTmpl *clone() const override
00090     {
00091         return new InterruptibleNodeTmpl(*this);
00092     }
00093 
00095     void set_scope(std::string scope)
00096     {
00097         scope_ = scope;
00098     }
00099 
00101     std::string scope() const
00102     {
00103         return scope_;
00104     }
00105 
00109     void add_interrupt(RoleType *role, MessageType *msg)
00110     {
00111         interrupts_.insert({ role, msg });
00112     }
00113 
00115     unsigned int num_interrupts() const
00116     {
00117         return interrupts_.size();
00118     }
00119 
00121     unsigned int num_interrupts(RoleType *role) const
00122     {
00123         return std::count_if(interrupts_.begin(), interrupts_.end(),
00124                 [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00125                     return (role->name() == pair.first->name());
00126                 });
00127     }
00128 
00132     MessageType *interrupt_msg(RoleType *role, unsigned int index) const
00133     {
00134         auto it = interrupts_.begin();
00135         for (unsigned int count=0; count <index; count++) {
00136             it = std::find_if(
00137                     ++it,
00138                     interrupts_.end(),
00139                     [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00140                         return (role->name() == pair.first->name());
00141                     });
00142         }
00143         return (*it).second;
00144     }
00145 
00146     typename InterruptType::const_iterator interrupt_begin() const
00147     {
00148         return interrupts_.begin();
00149     }
00150 
00151     typename InterruptType::const_iterator interrupt_end() const
00152     {
00153         return interrupts_.end();
00154     }
00155 
00159     void add_throw(RoleType *role, MessageType *msg)
00160     {
00161         throws_.insert({ role, msg });
00162     }
00163 
00165     unsigned int num_throws() const
00166     {
00167         return throws_.size();
00168     }
00169 
00171     unsigned int num_throws(RoleType *role) const
00172     {
00173         return std::count_if(throws_.begin(), throws_.end(),
00174                 [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00175                     return (role->name() == pair.first->name());
00176                 });
00177 
00178     }
00179 
00183     MessageType *throw_msg(RoleType *role, unsigned int index) const
00184     {
00185         auto it = throws_.begin();
00186         for (unsigned int count=0; count <index; count++) {
00187             it = std::find_if(
00188                     ++it,
00189                     throws_.end(),
00190                     [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00191                         return (role->name() == pair.first->name());
00192                     });
00193         }
00194         return (*it).second;
00195     }
00196 
00197     typename InterruptType::const_iterator throw_begin() const
00198     {
00199         return throws_.begin();
00200     }
00201 
00202     typename InterruptType::const_iterator throw_end() const
00203     {
00204         return throws_.end();
00205     }
00206 
00210     void add_catch(RoleType *role, MessageType *msg)
00211     {
00212         catches_.insert({ role, msg });
00213     }
00214 
00216     unsigned int num_catches() const
00217     {
00218         return catches_.size();
00219     }
00220 
00222     unsigned int num_catches(RoleType *role) const
00223     {
00224         return std::count_if(catches_.begin(), catches_.end(),
00225                 [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00226                     return (role->name() == pair.first->name());
00227                 });
00228     }
00229 
00233     MessageType *catch_msg(RoleType *role, unsigned int index) const
00234     {
00235         auto it = catches_.begin();
00236         for (unsigned int count=0; count <index; count++) {
00237             it = std::find_if(
00238                     ++it,
00239                     catches_.end(),
00240                     [role](std::pair<RoleType *, MessageType *> pair) -> bool {
00241                         return (role->name() == pair.first->name());
00242                     });
00243         }
00244         return (*it).second;
00245     }
00246 
00247     typename InterruptType::const_iterator catch_begin() const
00248     {
00249         return catches_.begin();
00250     }
00251 
00252     typename InterruptType::const_iterator catch_end() const
00253     {
00254         return catches_.end();
00255     }
00256 
00257     void accept(VisitorType &v) override;
00258 };
00259 
00260 using InterruptibleNode = InterruptibleNodeTmpl<Node, Role, MsgSig, util::NodeVisitor>;
00261 #endif // __cplusplus
00262 
00263 #ifdef __cplusplus
00264 extern "C" {
00265 #endif
00266 
00267 st_node *st_mk_interruptible_node_init();
00268 
00269 st_node *st_mk_interruptible_node_scoped(char *scope);
00270 
00271 st_node *st_interruptible_node_add_interrupt(st_node *const node, st_role *role, st_msg *msg);
00272 
00273 unsigned int st_interruptible_node_num_interrupts(st_node *const node, st_role *role);
00274 
00275 st_msg *st_interruptible_node_interrupt(st_node *const node, st_role *role, unsigned int index);
00276 
00277 st_node *st_interruptible_node_add_throw(st_node *const node, st_role *role, st_msg *msg);
00278 
00279 unsigned int st_interruptible_node_num_throws(st_node *const node, st_role *role);
00280 
00281 st_msg *st_interruptible_node_throw(st_node *const node, st_role *role, unsigned int index);
00282 
00283 st_node *st_interruptible_node_add_catch(st_node *const node, st_role *role, st_msg *msg);
00284 
00285 unsigned int st_interruptible_node_num_catches(st_node *const node, st_role *role);
00286 
00287 st_msg *st_interruptible_node_catch(st_node *const node, st_role *role, unsigned int index);
00288 
00289 #ifdef __cplusplus
00290 } // extern "C""
00291 #endif
00292 
00293 #ifdef __cplusplus
00294 } // namespace sesstype
00295 #endif
00296 
00297 #endif//SESSTYPE__NODE__INTERRUPTIBLE_H__
 All Classes Namespaces Files Functions