00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __NODE_HH
00019 # define __NODE_HH
00020
00021 # include <aurelia-config.hh>
00022
00023 # include <map>
00024 # include <unordered_set>
00025 # include <forward_list>
00026 # include "../max_shared/max_shared_ptr.hh"
00027 # include "../streams/buf_stream.hh"
00028 # include "../memory/pool_allocator.hh"
00029 # include "label.hh"
00030 # include "frame.hh"
00031 # ifndef NDEBUG
00032 # ifdef HAVE_CXXABI_H
00033 # include <cxxabi.h>
00034 # define DEMANGLE(X...) abi::__cxa_demangle(X,0,0,&status)
00035 # else
00036 # define DEMANGLE(X...) X
00037 # endif
00038 # endif
00039
00040 namespace aurelia {
00041 namespace llstack {
00042
00043 struct r_t;
00044 struct node;
00045
00046 }
00047 }
00048
00049 namespace std {
00050 template <>
00051 struct hash<aurelia::llstack::node> {
00052 unsigned operator()(const aurelia::llstack::node& a) const;
00053 };
00054 }
00055
00056 namespace aurelia {
00057 namespace llstack {
00058
00059 struct node_core {
00060 public:
00061 typedef std::forward_list<frame, pool_allocator<frame> > frame_list_t;
00062 typedef std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> > node_set_t;
00063 typedef std::map<stream, frame_list_t, std::less<stream>, pool_allocator<std::pair<stream, frame_list_t> > > p_t;
00064 private:
00065 label L;
00066 frame f;
00067 int pos;
00068 p_t P;
00069 node_set_t parents;
00070 unsigned _hash;
00071
00072 public:
00073 void update_hash();
00074 node_core(const label& L, const frame& f, int pos): L(L), f(f), pos(pos) {
00075 update_hash();
00076 }
00077
00078 node_core(const node_core& other): L(other.L), f(other.f), pos(other.pos) {
00079 _hash = other._hash;
00080 }
00081
00082 node_core(node_core&& other): L(std::move(other.L)),
00083 f(std::move(other.f)),
00084 pos(other.pos),
00085 _hash(other._hash) {
00086 }
00087
00088 node_core& operator=(const node_core& other) {
00089 return *this = node_core(other);
00090 }
00091
00092 node_core& operator=(node_core&& other) {
00093 std::swap(L, other.L);
00094 std::swap(f, other.f);
00095 std::swap(pos, other.pos);
00096 std::swap(P, other.P);
00097 std::swap(parents, other.parents);
00098 std::swap(_hash, other._hash);
00099 return *this;
00100 }
00101
00102 node_core() {
00103 _hash = 0;
00104 }
00105
00106 unsigned hash() const {
00107 return _hash;
00108 }
00109
00110 bool operator==(const node_core& other) const;
00111
00112 const node_set_t& get_parents() const {
00113 return parents;
00114 }
00115
00116 node_set_t& get_parents() {
00117 return parents;
00118 }
00119
00120 const p_t& get_P() const {
00121 return P;
00122 }
00123
00124 p_t& get_P() {
00125 return P;
00126 }
00127
00128 int get_pos() const {
00129 return pos;
00130 }
00131
00132 const label& get_label() const {
00133 return L;
00134 }
00135
00136 const frame& get_frame() const {
00137 return f;
00138 }
00139
00140 void drop(const stream& s) {
00141 for (p_t::iterator i = P.begin();
00142 i != P.end();) {
00143 if ((*i).first.get_pos() <= s.get_pos()) {
00144 P.erase(i);
00145 i = P.begin();
00146 } else break ;
00147 }
00148 }
00149 };
00150
00151 struct node: public max_shared_ptr<node_core> {
00152 private:
00153 typedef max_shared_ptr<node_core> super;
00154
00155 explicit node(const typename super::set_t::iterator& other): super(other) {
00156 }
00157
00158 node(const label& l, const frame& f, int s): super(l, f, s) {
00159 }
00160 node(const label& l, frame&& f, int s): super(l, std::move(f), s) {
00161 }
00162 public:
00163 node() = default;
00164
00165 node(const node& other): super(other) {
00166 }
00167
00168 node(node&& other): super(std::move(other)) {
00169 }
00170
00171 const node_core::node_set_t& parents() const {
00172 return (*this)->get_parents();
00173 }
00174
00175 node_core::node_set_t& parents() {
00176 return const_cast<node_core*>(&**this)->get_parents();
00177 }
00178
00179 const node_core::p_t& P() const {
00180 return (*this)->get_P();
00181 }
00182
00183 node_core::p_t& P() {
00184 return const_cast<node_core*>(&**this)->get_P();
00185 }
00186
00187 static node create(r_t& R, const label& l, const frame& f, const node& u,
00188 const stream& j);
00189
00190 static node boundary(const label&, const stream& s);
00191
00192 unsigned hash() const {
00193 return (*this)->hash();
00194 }
00195
00196 const label& get_label() const {
00197 return (*this)->get_label();
00198 }
00199
00200 int pos() const {
00201 return (*this)->get_pos();
00202 }
00203
00204 node& operator=(const node& other) {
00205 return *this = node(other);
00206 }
00207
00208 node& operator=(node&& other) {
00209 super::operator=(std::move(other));
00210 return *this;
00211 }
00212
00213 static void drop(const stream& s) {
00214 super::set_t::iterator i = super::set().begin();
00215 while (i != super::set().end()) {
00216 super::ptr& ro = *const_cast<super::ptr*>(&*i);
00217 ++ro.count();
00218 const_cast<node_core*>(&*ro)->drop(s);
00219 ++i;
00220 if (0 == --ro.count())
00221 set().erase(ro);
00222 }
00223 }
00224
00225 void mark(std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> >& marks) const {
00226 std::pair<std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> >::iterator, bool> j =
00227 marks.insert(*this);
00228 if (j.second) {
00229 for (node_core::node_set_t::const_iterator i =
00230 parents().begin();
00231 i != parents().end(); ++i) {
00232 (*i).mark(marks);
00233 }
00234 }
00235 }
00236
00237 static int nbnode() {
00238 return super::set().size();
00239 }
00240
00241 # ifndef NDEBUG
00242 static void printnodes(std::ostream& o) {
00243
00244 super::set_t::iterator i = super::set().begin();
00245 o << "digraph g {" << std::endl;
00246 while (i != super::set().end()) {
00247 super::ptr& ro = *const_cast<super::ptr*>(&*i);
00248
00249 o << "n_" << (*ro).get_label().hash()
00250 << "_" << (*ro).get_pos() << " [label=\""
00251 << (*ro).get_label().hash()
00252 << ", " << (*ro).get_pos() << "\"];" << std::endl;
00253
00254 ++i;
00255 }
00256 i = super::set().begin();
00257 while (i != super::set().end()) {
00258 super::ptr& ro = *const_cast<super::ptr*>(&*i);
00259 for (node_core::node_set_t::const_iterator j =
00260 (*ro).get_parents().begin();
00261 j != (*ro).get_parents().end(); ++j) {
00262 o << "n_" << ((*ro).get_label().hash())
00263 << "_" << (*ro).get_pos() << " -> " << "n_"
00264 << ((*j).get_label()).hash() << "_"
00265 << (*j).pos() << ";" << std::endl;
00266 }
00267 i++;
00268 }
00269 o << "}" << std::endl;
00270 }
00271 # endif
00272
00273 static void clear(std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> > marks
00274 = std::unordered_set<node, std::hash<node>, std::equal_to<node>, pool_allocator<node> >()) {
00275 super::set_t::iterator i = super::set().begin();
00276 while (i != super::set().end()) {
00277 if (marks.find(node(i))
00278 == marks.end()) {
00279 super::ptr& ro = *const_cast<super::ptr*>(&*i);
00280 const_cast<node_core*>(&*ro)->get_P().clear();
00281 if (!((*ro).get_parents().empty())) {
00282 ++ro.count();
00283 const_cast<node_core*>(&*ro)->get_parents().clear();
00284 --ro.count();
00285 set().erase(ro);
00286 i = super::set().begin();
00287 }
00288 else {
00289 i++;
00290 }
00291 } else {
00292 i++;
00293 }
00294 }
00295 }
00296
00297 template <typename Ret>
00298 void pop(r_t& queue, const Ret& ret_value, stream& j);
00299
00300 void pop(r_t& queue, const void_return&, stream& j);
00301
00302 template <typename Ret>
00303 void pop(r_t& queue, const Ret& ret_value, stream& j) const {
00304 node(*this).pop(queue, ret_value, j);
00305 }
00306 };
00307
00308 }
00309 }
00310
00311 #endif
00312