Back to index

texmacs  1.0.7.15
tree_pointer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tree_pointer.cpp
00004 * DESCRIPTION: Persistently point to trees (also used for linking)
00005 * COPYRIGHT  : (C) 2005  Joris van der Hoeven
00006 *******************************************************************************
00007 * An inverse path observer maintains the inverse path of the position
00008 * of the corresponding tree with respect to the global meta-tree.
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "modification.hpp"
00016 #include "link.hpp"
00017 #include "list.hpp"
00018 
00019 /******************************************************************************
00020 * Definition of the tree_pointer_rep class
00021 ******************************************************************************/
00022 
00023 class tree_pointer_rep: public observer_rep {
00024 private:
00025   tree_rep* ptr;
00026   bool flag;
00027 
00028 public:
00029   tree_pointer_rep (tree ref, bool flag2): ptr (ref.rep), flag (flag2) {}
00030   int get_type () { return OBSERVER_POINTER; }
00031   tm_ostream& print (tm_ostream& out) { return out << " pointer"; }
00032   void announce (tree& ref, modification mod) {
00033     (void) ref; link_announce (observer (this), mod); }
00034 
00035   void notify_assign      (tree& ref, tree t);
00036   void notify_insert      (tree& ref, int pos, int nr);
00037   void notify_remove      (tree& ref, int pos, int nr);
00038   void notify_split       (tree& ref, int pos, tree prev);
00039   void notify_var_split   (tree& ref, tree t1, tree t2);
00040   void notify_join        (tree& ref, int pos, tree next);
00041   void notify_var_join    (tree& ref, tree t, int offset);
00042   void notify_assign_node (tree& ref, tree_label op);
00043   void notify_insert_node (tree& ref, int pos);
00044   void notify_remove_node (tree& ref, int pos);
00045   void notify_detach      (tree& ref, tree closest, bool right);
00046 
00047   list<observer> get_tree_pointers ();
00048   bool set_tree (tree t);
00049   bool get_tree (tree& t);
00050 };
00051 
00052 /******************************************************************************
00053 * Specific routines for tree_pointer observers
00054 ******************************************************************************/
00055 
00056 list<observer>
00057 tree_pointer_rep::get_tree_pointers () {
00058   return list<observer> (observer (this));
00059 }
00060 
00061 bool
00062 tree_pointer_rep::get_tree (tree& t) {
00063   t= tree (ptr);
00064   return true;
00065 }
00066 
00067 bool
00068 tree_pointer_rep::set_tree (tree t) {
00069   if (ptr != t.rep) {
00070     tree ref (ptr);
00071     remove_observer (ref->obs, observer (this));
00072     ptr= t.rep;
00073     insert_observer (t->obs, observer (this));
00074   }
00075   return true;
00076 }
00077 
00078 /******************************************************************************
00079 * Call back routines for modifications
00080 ******************************************************************************/
00081 
00082 void
00083 tree_pointer_rep::notify_assign (tree& ref, tree t) {
00084   // cout << "Notify assign " << ref << ", " << t << "\n";
00085   (void) ref; (void) set_tree (t);
00086   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00087 }
00088 
00089 void
00090 tree_pointer_rep::notify_insert (tree& ref, int pos, int nr) {
00091   // cout << "Notify insert " << ref << ", " << pos << ", " << nr << "\n";
00092   (void) ref; (void) pos; (void) nr;
00093   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00094 }
00095 
00096 void
00097 tree_pointer_rep::notify_remove (tree& ref, int pos, int nr) {
00098   // cout << "Notify remove " << ref << ", " << pos << ", " << nr << "\n";
00099   (void) ref; (void) pos; (void) nr;
00100   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00101 }
00102 
00103 void
00104 tree_pointer_rep::notify_split (tree& ref, int pos, tree prev) {
00105   (void) ref; (void) pos; (void) prev;
00106 }
00107 
00108 void
00109 tree_pointer_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00110   // cout << "Notify var split " << ref << ", " << t1 << ", " << t2 << "\n";
00111   (void) t2; (void) ref;
00112   (void) set_tree (t1); // always at the left
00113   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00114 }
00115 
00116 void
00117 tree_pointer_rep::notify_join (tree& ref, int pos, tree next) {
00118   (void) ref; (void) pos; (void) next;
00119 }
00120 
00121 void
00122 tree_pointer_rep::notify_var_join (tree& ref, tree t, int offset) {
00123   // cout << "Notify var join " << ref << ", " << t << ", " << offset << "\n";
00124   (void) ref; (void) offset;
00125   (void) set_tree (t);
00126   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00127 }
00128 
00129 void
00130 tree_pointer_rep::notify_assign_node (tree& ref, tree_label op) {
00131   // cout << "Notify assign node " << ref << ", " << as_string (op) << "\n";
00132   (void) ref; (void) op;
00133   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00134 }
00135 
00136 void
00137 tree_pointer_rep::notify_insert_node (tree& ref, int pos) {
00138   //cout << "Notify insert node " << ref << ", " << pos << "\n";
00139   (void) ref; (void) pos;
00140   if (flag) {
00141     remove_observer (ref[pos]->obs, observer (this));
00142     ptr= ref.rep;
00143     insert_observer (ref->obs, observer (this));    
00144   }
00145   //cout << "position -> " << obtain_position (observer (this)) << "\n";
00146 }
00147 
00148 void
00149 tree_pointer_rep::notify_remove_node (tree& ref, int pos) {
00150   // cout << "Notify remove node " << ref << ", " << pos << "\n";
00151   (void) set_tree (ref[pos]);
00152   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00153 }
00154 
00155 void
00156 tree_pointer_rep::notify_detach (tree& ref, tree closest, bool right) {
00157   // cout << "Notify detach " << ref << ", " << closest <<", "<< right << "\n";
00158   (void) right; (void) ref;
00159   (void) set_tree (closest);
00160   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00161 }
00162 
00163 /******************************************************************************
00164 * Public interface
00165 ******************************************************************************/
00166 
00167 observer
00168 tree_pointer (tree ref, bool flag) {
00169   return tm_new<tree_pointer_rep> (ref, flag);
00170 }
00171 
00172 tree
00173 obtain_tree (observer obs) {
00174   tree t;
00175   (void) obs->get_tree (t);
00176   return t;
00177 }
00178 
00179 observer
00180 tree_pointer_new (tree ref) {
00181   observer obs= tree_pointer (ref);
00182   attach_observer (ref, obs);
00183   return obs;
00184 }
00185 
00186 void
00187 tree_pointer_delete (observer obs) {
00188   tree ref= obtain_tree (obs);
00189   detach_observer (ref, obs);
00190 }