![]() |
libsesstype
2.0.0
Library for Session Types programming.
|
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__