- Timestamp:
- May 9, 2019, 2:31:15 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2bb4a01
- Parents:
- ee7a29f
- Location:
- src/AST
- Files:
-
- 3 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Node.hpp
ree7a29f rf47f887 4 4 5 5 namespace ast { 6 class Node { 7 public: 8 virtual ~Node() = default; 6 9 7 class Node { 8 public: 9 virtual ~Node() = default; 10 enum class ref_type { 11 strong, 12 weak 13 }; 10 14 11 enum class ref_type { 12 strong, 13 weak 14 }; 15 inline void increment(ref_type ref) const { 16 switch (ref) { 17 case ref_type::strong: strong_ref++; break; 18 case ref_type::weak : weak_ref ++; break; 19 } 20 } 15 21 16 void increment(ref_type ref) { 17 switch (ref) { 18 case ref_type::strong: strong_ref++; break; 19 case ref_type::weak : weak_ref ++; break; 20 } 22 inline void decrement(ref_type ref) const { 23 switch (ref) { 24 case ref_type::strong: strong_ref--; break; 25 case ref_type::weak : weak_ref --; break; 21 26 } 22 27 23 void decrement(ref_type ref) { 24 switch (ref) { 25 case ref_type::strong: strong_ref--; break; 26 case ref_type::weak : weak_ref --; break; 27 } 28 29 if(!strong_ref && !weak_ref) { 30 delete this; 31 } 28 if(!strong_ref && !weak_ref) { 29 delete this; 32 30 } 33 34 template<typename node_t>35 friend auto mutate(const node_t * node);36 37 private:38 size_t strong_ref = 0;39 size_t weak_ref = 0;40 };41 42 // Mutate a node, non-member function to avoid static type43 // problems and be able to use auto return44 template<typename node_t>45 auto mutate(const node_t * node) {46 assertf(47 node->strong_count >= 1,48 "Error: attempting to mutate a node that appears to have been linked"49 );50 if (node->strong_count == 1) {51 return const_cast<node_t *>(node);52 }53 54 assertf(55 node->weak_count == 0,56 "Error: mutating node with weak references to it will invalided some references"57 );58 return node->clone();59 31 } 60 32 61 // All accept routines should look as follows : 62 // virtual void accept( Visitor &v ) override { 63 // return v.visit(this); 64 // } 65 // Using the following wrapper to handle the node type 66 template< typename node_t > 67 auto visit_this( visitor & v, node_t * node ) { 68 ptr<node_t> p; 69 p.node = node; 70 auto r = v.visit(p); 71 p.node = nullptr; 72 return r; 33 template<typename node_t> 34 friend auto mutate(const node_t * node); 35 36 private: 37 mutable size_t strong_ref = 0; 38 mutable size_t weak_ref = 0; 39 }; 40 41 // Mutate a node, non-member function to avoid static type 42 // problems and be able to use auto return 43 template<typename node_t> 44 auto mutate(const node_t * node) { 45 assertf( 46 node->strong_count >= 1, 47 "Error: attempting to mutate a node that appears to have been linked" 48 ); 49 if (node->strong_count == 1) { 50 return const_cast<node_t *>(node); 73 51 } 74 52 75 // Base class for the smart pointer types 76 // should never really be used. 77 template< typename node_t, enum Node::ref_type ref_t> 78 class ptr_base { 79 public: 80 ptr_base() : node(nullptr) {} 81 ptr_base( node_t * n ) : node(n) { if( !node ) node->increment(ref_t); } 82 ~ptr_base() { if( node ) node->decrement(ref_t); } 53 assertf( 54 node->weak_count == 0, 55 "Error: mutating node with weak references to it will invalided some references" 56 ); 57 return node->clone(); 58 } 83 59 84 template< enum Node::ref_type o_ref_t > 85 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) { 86 if( !node ) return; 87 node->increment(ref_t); 88 } 60 // Base class for the smart pointer types 61 // should never really be used. 62 template< typename node_t, enum Node::ref_type ref_t> 63 class ptr_base { 64 public: 65 ptr_base() : node(nullptr) {} 66 ptr_base( node_t * n ) : node(n) { if( !node ) node->increment(ref_t); } 67 ~ptr_base() { if( node ) node->decrement(ref_t); } 89 68 90 91 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {92 if( node ) node->increment(ref_t);93 if( node ) node->decrement(o_ref_t);94 69 template< enum Node::ref_type o_ref_t > 70 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) { 71 if( !node ) return; 72 node->increment(ref_t); 73 } 95 74 96 97 ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o) {98 assign(o.node);99 return *this;100 75 template< enum Node::ref_type o_ref_t > 76 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) { 77 if( node ) node->increment(ref_t); 78 if( node ) node->decrement(o_ref_t); 79 } 101 80 102 template< enum Node::ref_type o_ref_t > 103 ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) { 104 if(o.node == node) return *this; 105 assign(o.node); 106 if( node ) node->decrement(o_ref_t); 107 return *this; 108 } 81 template< enum Node::ref_type o_ref_t > 82 ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) { 83 assign(o.node); 84 return *this; 85 } 109 86 110 const node_t * get() const { return node; } 111 const node_t * operator->() const { return node; } 112 const node_t & operator* () const { return *node; } 113 operator bool() const { return node; } 87 template< enum Node::ref_type o_ref_t > 88 ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) { 89 if(o.node == node) return *this; 90 assign(o.node); 91 if( node ) node->decrement(o_ref_t); 92 return *this; 93 } 114 94 115 private: 116 void assign(node_t * other ) { 117 if( other ) other->increment(ref_t); 118 if( node ) node ->decrement(ref_t); 119 node = other; 120 } 95 const node_t * get() const { return node; } 96 const node_t * operator->() const { return node; } 97 const node_t & operator* () const { return *node; } 98 explicit operator bool() const { return node; } 99 operator const node_t * const() const { return node; } 121 100 122 protected: 123 node_t * node; 124 }; 101 using ptr = const node_t *; 125 102 126 template< typename node_t > 127 using ptr = ptr_base< node_t, Node::ref_type::strong >; 103 private: 104 void assign(node_t * other ) { 105 if( other ) other->increment(ref_t); 106 if( node ) node ->decrement(ref_t); 107 node = other; 108 } 128 109 129 template< typename node_t > 130 using readonly = ptr_base< node_t, Node::ref_type::weak >; 110 protected: 111 node_t * node; 112 }; 113 114 template< typename node_t > 115 using ptr = ptr_base< node_t, Node::ref_type::strong >; 116 117 template< typename node_t > 118 using readonly = ptr_base< node_t, Node::ref_type::weak >; 131 119 }
Note: See TracChangeset
for help on using the changeset viewer.