Paradiseo-eo sources added

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@40 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
legrand 2006-12-12 14:49:08 +00:00
commit c3aec878e5
3609 changed files with 342772 additions and 0 deletions

View file

@ -0,0 +1,862 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>EO: parse_tree.h Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"> <form class="search" action="search.php" method="get">
<a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a> | <span class="search"><u>S</u>earch&nbsp;for&nbsp;<input class="search" type="text" name="query" value="" size="20" accesskey="s"/></span></form></div>
<div class="nav">
<a class="el" href="dir_000000.html">src</a>&nbsp;/&nbsp;<a class="el" href="dir_000017.html">gp</a></div>
<h1>parse_tree.h</h1><div class="fragment"><pre class="fragment">00001 <span class="preprocessor">#ifndef PARSE_TREE_HH</span>
00002 <span class="preprocessor"></span><span class="preprocessor">#define PARSE_TREE_HH</span>
00003 <span class="preprocessor"></span>
00155 <span class="preprocessor">#include &lt;vector&gt;</span>
00156 <span class="preprocessor">#include &lt;utility&gt;</span> <span class="comment">// for swap</span>
00157
00158 <span class="preprocessor">#ifdef _MSC_VER</span>
00159 <span class="preprocessor"></span><span class="preprocessor">#pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger</span>
00160 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
00161 <span class="preprocessor"></span>
<a name="l00162"></a><a class="code" href="namespacegp__parse__tree.html">00162</a> <span class="keyword">namespace </span>gp_parse_tree
00163 {
00164
00165 <span class="preprocessor">#include "node_pool.h"</span>
00166
00168 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
00169 <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(T&amp; a, T&amp; b)
00170 {
00171 T tmp = a;
00172 a = b;
00173 b = tmp;
00174 }
00175
00176 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt; <span class="keyword">class </span>parse_tree
00177 {
00178 <span class="keyword">public</span> :
00179
00180
00181 <span class="keyword">class </span>subtree
00182 {
00183
00184 <span class="comment">/*</span>
<a name="l00185"></a><a class="code" href="classgp__parse__tree_1_1_mem_pool.html">00185</a> <span class="comment"> a bit nasty way to use a pool allocator (which would otherwise use slooow new and delete)</span>
00186 <span class="comment"> TODO: use the std::allocator interface</span>
00187 <span class="comment">*/</span>
00188
00189 <span class="preprocessor">#if (defined(__GNUC__) || defined(_MSC_VER)) &amp;&amp; !(defined(_MT) || defined(MACOSX) || defined(__APPLE__)) // not multithreaded (or MACOSX - J. Eggermont)</span>
00190 <span class="preprocessor"></span> Node_alloc&lt;T&gt; node_allocator;
00191 Tree_alloc&lt;subtree&gt; tree_allocator;
00192 <span class="preprocessor">#else</span>
00193 <span class="preprocessor"></span> Standard_Node_alloc&lt;T&gt; node_allocator;
00194 Standard_alloc&lt;subtree&gt; tree_allocator;
00195 <span class="preprocessor">#endif</span>
00196 <span class="preprocessor"></span>
00197 <span class="keyword">public</span> :
00198
00199 <span class="keyword">typedef</span> subtree* iterator;
00200 <span class="keyword">typedef</span> <span class="keyword">const</span> subtree* const_iterator;
00201
00202 <span class="comment">/* Constructors, assignments */</span>
00203
00204 subtree(<span class="keywordtype">void</span>) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00205 {}
00206 subtree(<span class="keyword">const</span> subtree&amp; s)
00207 : content(node_allocator.allocate()),
00208 args(0),
00209 parent(0),
00210 _cumulative_size(1),
00211 _depth(1),
00212 _size(1)
00213 {
00214 copy(s);
00215 }
00216
00217 subtree(<span class="keyword">const</span> T&amp; t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00218 { copy(t); }
00219
00220 <span class="keyword">template</span> &lt;<span class="keyword">class</span> It&gt;
00221 subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00222 { <span class="comment">// initialize in prefix order for efficiency reasons</span>
00223 init(b, --e);
00224 }
00225
00226 <span class="keyword">virtual</span> ~subtree(<span class="keywordtype">void</span>) { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); }
00227
00228 subtree&amp; operator=(<span class="keyword">const</span> subtree&amp; s)
00229 {
00230 <span class="keywordflow">if</span> (s.get_root() == get_root())
00231 { <span class="comment">// from the same tree, maybe a child. Don't take any chances</span>
00232 subtree anotherS = s;
00233 <span class="keywordflow">return</span> copy(anotherS);
00234 }
00235
00236 copy(s);
00237 updateAfterInsert();
00238 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00239 }
00240
00241 subtree&amp; operator=(<span class="keyword">const</span> T&amp; t) { copy(t); updateAfterInsert(); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00242
00243 <span class="comment">/* Access to the nodes */</span>
00244
00245 T&amp; operator*(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> *content; }
00246 <span class="keyword">const</span> T&amp; operator*(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> *content; }
00247 T* operator-&gt;(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> content; }
00248 <span class="keyword">const</span> T* operator-&gt;(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> content; }
00249
00250 <span class="comment">/* Equality, inequality check, Node needs to implement operator== */</span>
00251
00252 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> subtree&amp; other)<span class="keyword"> const</span>
00253 <span class="keyword"> </span>{
00254 <span class="keywordflow">if</span> (! (*content == *other.content))
00255 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00256
00257 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; arity(); i++)
00258 {
00259 <span class="keywordflow">if</span> (!(args[i] == other.args[i]))
00260 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00261 }
00262
00263 <span class="keywordflow">return</span> <span class="keyword">true</span>;
00264 }
00265
00266 <span class="keywordtype">bool</span> operator !=(<span class="keyword">const</span> subtree&amp; other)<span class="keyword"> const</span>
00267 <span class="keyword"> </span>{
00268 <span class="keywordflow">return</span> !operator==(other);
00269 }
00270
00271 <span class="comment">/* Arity */</span>
00272 <span class="keywordtype">int</span> arity(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> content-&gt;arity(); }
00273
00274 <span class="comment">/* Evaluation with an increasing amount of user defined arguments */</span>
00275 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal&gt;
00276 <span class="keywordtype">void</span> apply(RetVal&amp; v)<span class="keyword"> const </span>{ (*content)(v, begin()); }
00277
00278 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal, <span class="keyword">class</span> It&gt;
00279 <span class="keywordtype">void</span> apply(RetVal&amp; v, It values)<span class="keyword"> const</span>
00280 <span class="keyword"> </span>{
00281 (*content)(v, begin(), values);
00282 }
00283
00284 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal, <span class="keyword">class</span> It&gt;
00285 <span class="keywordtype">void</span> apply_mem_func(RetVal&amp; v, It misc, <span class="keywordtype">void</span> (T::* f)(RetVal&amp;, <span class="keyword">typename</span> subtree::iterator, It))
00286 {
00287 (content-&gt;*f)(v, begin(), misc);
00288 }
00289
00290
00291 <span class="comment">/* template &lt;class RetVal, class It, class It2&gt;</span>
00292 <span class="comment"> void apply(RetVal&amp; v, It values, It2 moreValues) const</span>
00293 <span class="comment"> { (*content)(v, begin(), values, moreValues); }</span>
00294 <span class="comment"></span>
00295 <span class="comment"> template &lt;class RetVal, class It, class It2, class It3&gt;</span>
00296 <span class="comment"> void apply(RetVal&amp; v, It values, It2 moreValues, It3 evenMoreValues) const</span>
00297 <span class="comment"> { (*content)(v, begin(), values, moreValues, evenMoreValues); }</span>
00298 <span class="comment">*/</span>
00299
00300 <span class="keyword">template</span> &lt;<span class="keyword">class</span> Pred&gt;
00301 <span class="keywordtype">void</span> find_nodes(std::vector&lt;subtree*&gt;&amp; result, Pred&amp; p)
00302 {
00303 <span class="keywordflow">if</span> (p(*content))
00304 {
00305 result.push_back(<span class="keyword">this</span>);
00306 }
00307
00308 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; arity(); ++i)
00309 {
00310 args[i].find_nodes(result, p);
00311 }
00312 }
00313
00314 <span class="keyword">template</span> &lt;<span class="keyword">class</span> Pred&gt;
00315 <span class="keywordtype">void</span> find_nodes(std::vector&lt;const subtree*&gt;&amp; result, Pred&amp; p)<span class="keyword"> const</span>
00316 <span class="keyword"> </span>{
00317 <span class="keywordflow">if</span> (p(*content))
00318 {
00319 result.push_back(<span class="keyword">this</span>);
00320 }
00321
00322 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; arity(); ++i)
00323 {
00324 args[i].find_nodes(result, p);
00325 }
00326 }
00327
00328 <span class="comment">/* Iterators */</span>
00329
00330 iterator begin(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> args; }
00331 const_iterator begin(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> args; }
00332
00333 iterator end(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> args + arity(); }
00334 const_iterator end(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> args + arity(); }
00335
00336 subtree&amp; operator[](<span class="keywordtype">int</span> i) { <span class="keywordflow">return</span> *(begin() + i); }
00337 <span class="keyword">const</span> subtree&amp; operator[](<span class="keywordtype">int</span> i)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> *(begin() + i); }
00338
00339 <span class="comment">/* Some statistics */</span>
00340
00341 size_t size(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _size; }
00342
00343 size_t cumulative_size(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _cumulative_size; }
00344 size_t depth(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _depth; }
00345
00346 <span class="keyword">const</span> subtree&amp; select_cumulative(size_t which)<span class="keyword"> const</span>
00347 <span class="keyword"> </span>{ <span class="keywordflow">return</span> imp_select_cumulative(which); }
00348
00349 subtree&amp; select_cumulative(size_t which)
00350 { <span class="keywordflow">return</span> const_cast&lt;subtree&amp;&gt;(imp_select_cumulative(which)); }
00351
00352 subtree&amp; get_node(size_t which)
00353 { <span class="keywordflow">return</span> const_cast&lt;subtree&amp;&gt;(imp_get_node(which));}
00354 <span class="keyword">const</span> subtree&amp; get_node(size_t which)<span class="keyword"> const</span>
00355 <span class="keyword"> </span>{ <span class="keywordflow">return</span> imp_get_node(which); }
00356
00357 subtree* get_parent(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> parent; }
00358 <span class="keyword">const</span> subtree* get_parent(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> parent; }
00359
00360 <span class="keywordtype">void</span> clear(<span class="keywordtype">void</span>)
00361 { tree_allocator.deallocate(args, arity()); args = 0; *content = T(); parent = 0; _cumulative_size = 0; _depth = 0; _size = 0; }
00362
00363 <span class="keywordtype">void</span> swap(subtree&amp; y)
00364 {
00365 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(content, y.content);
00366 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(args, y.args);
00367
00368 adopt();
00369 y.adopt();
00370
00371 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(parent, y.parent);
00372
00373 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(_cumulative_size, y._cumulative_size);
00374 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(_depth, y._depth);
00375 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(_size, y._size);
00376 updateAfterInsert();
00377 }
00378
00379 <span class="keyword">protected</span> :
00380
00381 <span class="keyword">virtual</span> <span class="keywordtype">void</span> updateAfterInsert(<span class="keywordtype">void</span>)
00382 {
00383 _depth = 0;
00384 _size = 1;
00385 _cumulative_size = 0;
00386
00387 <span class="keywordflow">for</span> (iterator it = begin(); it != end(); ++it)
00388 {
00389 _size += it-&gt;size();
00390 _cumulative_size += it-&gt;_cumulative_size;
00391 _depth = it-&gt;_depth &gt; _depth? it-&gt;_depth: _depth;
00392 }
00393 _cumulative_size += _size;
00394 _depth++;
00395
00396 <span class="keywordflow">if</span> (parent)
00397 parent-&gt;updateAfterInsert();
00398 }
00399
00400 <span class="keyword">private</span> :
00401
00402 <span class="keyword">const</span> subtree&amp; imp_select_cumulative(size_t which)<span class="keyword"> const</span>
00403 <span class="keyword"> </span>{
00404 <span class="keywordflow">if</span> (which &gt;= (_cumulative_size - size()))
00405 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00406 <span class="comment">// else</span>
00407
00408 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = arity() - 1; i &gt;= 0; --i)
00409 {
00410 <span class="keywordflow">if</span> (which &lt; args[i]._cumulative_size)
00411 <span class="keywordflow">return</span> args[i].imp_select_cumulative(which);
00412 which -= args[i]._cumulative_size;
00413 }
00414
00415 <span class="keywordflow">return</span> *<span class="keyword">this</span>; <span class="comment">// error!</span>
00416 }
00417
00418 <span class="keyword">const</span> subtree&amp; imp_get_node(size_t which)<span class="keyword"> const</span>
00419 <span class="keyword"> </span>{
00420 <span class="keywordflow">if</span> (which == size() - 1)
00421 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00422
00423 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = arity() - 1; i &gt;= 0; --i)
00424 {
00425 <span class="keywordtype">unsigned</span> c_size = args[i].size();
00426 <span class="keywordflow">if</span> (which &lt; c_size)
00427 <span class="keywordflow">return</span> args[i].imp_get_node(which);
00428 which -= c_size;
00429 }
00430
00431 <span class="keywordflow">return</span> *<span class="keyword">this</span>; <span class="comment">// error!</span>
00432 }
00433
00434 <span class="keyword">const</span> subtree* get_root(<span class="keywordtype">void</span>)<span class="keyword"> const</span>
00435 <span class="keyword"> </span>{
00436 <span class="keywordflow">if</span> (parent == 0)
00437 <span class="keywordflow">return</span> <span class="keyword">this</span>;
00438 <span class="comment">// else</span>
00439
00440 <span class="keywordflow">return</span> parent-&gt;get_root();
00441 }
00442 subtree&amp; copy(<span class="keyword">const</span> subtree&amp; s)
00443 {
00444 <span class="keywordtype">int</span> old_arity = arity();
00445
00446 <span class="keywordtype">int</span> new_arity = s.arity();
00447
00448 <span class="keywordflow">if</span> (new_arity != old_arity)
00449 {
00450 tree_allocator.deallocate(args, old_arity);
00451
00452 args = tree_allocator.allocate(new_arity);
00453 }
00454
00455 <span class="keywordflow">switch</span>(new_arity)
00456 {
00457 <span class="keywordflow">case</span> 3 : args[2].copy(s.args[2]); args[2].parent = <span class="keyword">this</span>; <span class="comment">// no break!</span>
00458 <span class="keywordflow">case</span> 2 : args[1].copy(s.args[1]); args[1].parent = <span class="keyword">this</span>;
00459 <span class="keywordflow">case</span> 1 : args[0].copy(s.args[0]); args[0].parent = <span class="keyword">this</span>;
00460 <span class="keywordflow">case</span> 0 : <span class="keywordflow">break</span>;
00461 <span class="keywordflow">default</span> :
00462 {
00463 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; new_arity; ++i)
00464 {
00465 args[i].copy(s.args[i]);
00466 args[i].parent = <span class="keyword">this</span>;
00467 }
00468 }
00469 }
00470
00471 *content = *s.content;
00472 _size = s._size;
00473 _depth = s._depth;
00474 _cumulative_size = s._cumulative_size;
00475
00476 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00477 }
00478
00479 subtree&amp; copy(<span class="keyword">const</span> T&amp; t)
00480 {
<a name="l00481"></a><a class="code" href="namespacegp__parse__tree.html#a0">00481</a> <span class="keywordtype">int</span> oldArity = arity();
00482
00483 <span class="keywordflow">if</span> (content != &amp;t)
00484 *content = t;
00485 <span class="keywordflow">else</span>
00486 oldArity = -1;
00487
00488 <span class="keywordtype">int</span> ar = arity();
00489
00490 <span class="keywordflow">if</span> (ar != oldArity)
00491 {
00492 <span class="keywordflow">if</span> (oldArity != -1)
00493 tree_allocator.deallocate(args, oldArity);
00494
00495 args = tree_allocator.allocate(ar);
00496
00497 <span class="comment">//if (ar &gt; 0)</span>
00498 <span class="comment">// args = new subtree [ar];</span>
00499 <span class="comment">//else</span>
00500 <span class="comment">// args = 0;</span>
00501 }
00502
00503 adopt();
00504 updateAfterInsert();
00505 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00506 }
00507
00508 <span class="keywordtype">void</span> disown(<span class="keywordtype">void</span>)
00509 {
00510 <span class="keywordflow">switch</span>(arity())
00511 {
00512 <span class="keywordflow">case</span> 3 : args[2].parent = 0; <span class="comment">// no break!</span>
00513 <span class="keywordflow">case</span> 2 : args[1].parent = 0;
00514 <span class="keywordflow">case</span> 1 : args[0].parent = 0; <span class="keywordflow">break</span>;
00515 <span class="keywordflow">case</span> 0 : <span class="keywordflow">break</span>;
00516 <span class="keywordflow">default</span> :
00517 {
00518 <span class="keywordflow">for</span> (iterator it = begin(); it != end(); ++it)
00519 {
00520 it-&gt;parent = 0;
00521 }
00522 }
00523 }
00524
00525 }
00526
00527 <span class="keywordtype">void</span> adopt(<span class="keywordtype">void</span>)
00528 {
00529 <span class="keywordflow">switch</span>(arity())
00530 {
00531 <span class="keywordflow">case</span> 3 : args[2].parent = <span class="keyword">this</span>; <span class="comment">// no break!</span>
00532 <span class="keywordflow">case</span> 2 : args[1].parent = <span class="keyword">this</span>;
00533 <span class="keywordflow">case</span> 1 : args[0].parent = <span class="keyword">this</span>; <span class="keywordflow">break</span>;
00534 <span class="keywordflow">case</span> 0 : <span class="keywordflow">break</span>;
00535 <span class="keywordflow">default</span> :
00536 {
00537 <span class="keywordflow">for</span> (iterator it = begin(); it != end(); ++it)
00538 {
00539 it-&gt;parent = <span class="keyword">this</span>;
00540 }
00541 }
00542 }
00543 }
00544
00545 <span class="keyword">template</span> &lt;<span class="keyword">class</span> It&gt;
00546 <span class="keywordtype">void</span> init(It b, It&amp; last)
00547 {
00548 *<span class="keyword">this</span> = *last;
00549
00550 <span class="preprocessor">#ifndef NDEBUG</span>
00551 <span class="preprocessor"></span> <span class="keywordflow">if</span> (last == b &amp;&amp; arity() &gt; 0)
00552 {
00553 <span class="keywordflow">throw</span> <span class="stringliteral">"subtree::init()"</span>;
00554 }
00555 <span class="preprocessor">#endif</span>
00556 <span class="preprocessor"></span>
00557 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; arity(); ++i)
00558 {
00559 args[i].parent = 0;
00560 args[i].init(b, --last);
00561 args[i].parent = <span class="keyword">this</span>;
00562 }
00563
00564 updateAfterInsert();
00565 }
00566
00567 T* content;
00568 subtree* args;
00569 subtree* parent;
00570
00571 size_t _cumulative_size;
00572 size_t _depth;
00573 size_t _size;
00574 };
00575
00576 <span class="comment">// Continuing with parse_tree</span>
00577
00578 <span class="keyword">typedef</span> T value_type;
00579
00580 <span class="comment">/* Constructors and Assignments */</span>
00581
00582 parse_tree(<span class="keywordtype">void</span>) : _root(), pushed() {}
00583 parse_tree(<span class="keyword">const</span> parse_tree&amp; org) : _root(org._root), pushed(org.pushed) { }
00584 parse_tree(<span class="keyword">const</span> subtree&amp; sub) : _root(sub), pushed() { }
00585
00586 <span class="keyword">template</span> &lt;<span class="keyword">class</span> It&gt;
00587 parse_tree(It b, It e) : _root(b, e), pushed() {}
00588
00589 <span class="keyword">virtual</span> ~parse_tree(<span class="keywordtype">void</span>) {}
00590
00591 parse_tree&amp; operator=(<span class="keyword">const</span> parse_tree&amp; org) { <span class="keywordflow">return</span> copy(org); }
00592 parse_tree&amp; operator=(<span class="keyword">const</span> subtree&amp; sub)
00593 { <span class="keywordflow">return</span> copy(sub); }
00594
00595
00596 <span class="comment">/* Equality and inequality */</span>
00597
00598 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> parse_tree&amp; other)<span class="keyword"> const</span>
00599 <span class="keyword"> </span>{ <span class="keywordflow">return</span> _root == other._root; }
00600
00601 <span class="keywordtype">bool</span> operator !=(<span class="keyword">const</span> parse_tree&amp; other)<span class="keyword"> const</span>
00602 <span class="keyword"> </span>{ <span class="keywordflow">return</span> !operator==(other); }
00603
00604 <span class="comment">/* Simple tree statistics */</span>
00605
00606 size_t size(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _root.size(); }
00607 size_t depth(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _root.depth(); }
00608 <span class="keywordtype">void</span> clear(<span class="keywordtype">void</span>) { _root.clear(); pushed.resize(0); }
00609
00610 <span class="comment">/* Evaluation (application), with an increasing number of user defined arguments */</span>
00611
00612 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal&gt;
00613 <span class="keywordtype">void</span> apply(RetVal&amp; v)<span class="keyword"> const</span>
00614 <span class="keyword"> </span>{ _root.apply(v); }
00615
00616 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal, <span class="keyword">class</span> It&gt;
00617 <span class="keywordtype">void</span> apply(RetVal&amp; v, It varValues)<span class="keyword"> const</span>
00618 <span class="keyword"> </span>{ _root.apply(v, varValues); }
00619
00620 <span class="keyword">template</span> &lt;<span class="keyword">class</span> RetVal, <span class="keyword">class</span> It&gt;
00621 <span class="keywordtype">void</span> apply_mem_func(RetVal&amp; v, It misc, <span class="keywordtype">void</span> (T::* f)(RetVal&amp;, <span class="keyword">typename</span> subtree::iterator, It))
00622 {
00623 _root.apply_mem_func(v, misc, f);
00624 }
00625
00626 <span class="comment">//template &lt;class RetVal, class It, class It2&gt;</span>
00627 <span class="comment">// void apply(RetVal&amp; v, It varValues, It2 moreValues) const</span>
00628 <span class="comment">// { _root.apply(v, varValues, moreValues); }</span>
00629
00630 <span class="comment">//template &lt;class RetVal, class It, class It2, class It3&gt;</span>
00631 <span class="comment">// void apply(RetVal&amp; v, It varValues, It2 moreValues, It3 evenMoreValues) const</span>
00632 <span class="comment">// { _root.apply(v, varValues, moreValues, evenMoreValues); }</span>
00633
00634 <span class="keyword">template</span> &lt;<span class="keyword">class</span> Pred&gt;
00635 <span class="keywordtype">void</span> find_nodes(std::vector&lt;subtree*&gt;&amp; result, Pred&amp; p)
00636 {
00637 _root.find_nodes(result, p);
00638 }
00639
00640 <span class="keyword">template</span> &lt;<span class="keyword">class</span> Pred&gt;
00641 <span class="keywordtype">void</span> find_nodes(std::vector&lt;const subtree*&gt;&amp; result, Pred&amp; p)<span class="keyword"> const</span>
00642 <span class="keyword"> </span>{
00643 _root.find_nodes(p);
00644 }
00645
00646 <span class="comment">/* Customized Swap */</span>
00647 <span class="keywordtype">void</span> swap(parse_tree&lt;T&gt;&amp; other)
00648 {
00649 <a class="code" href="namespacegp__parse__tree.html#a0">do_the_swap</a>(pushed, other.pushed);
00650 _root.swap(other._root);
00651 }
00652
00653 <span class="comment">/* Definitions of the iterators */</span>
00654
00655 <span class="keyword">class </span>base_iterator
00656 {
00657 <span class="keyword">public</span> :
00658
00659 base_iterator() {}
00660 base_iterator(subtree* n) { node = n; }
00661
00662 base_iterator&amp; operator=(<span class="keyword">const</span> base_iterator&amp; org)
00663 { node = org.node; <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00664
00665 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> base_iterator&amp; org)<span class="keyword"> const</span>
00666 <span class="keyword"> </span>{ <span class="keywordflow">return</span> node == org.node; }
00667 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> base_iterator&amp; org)<span class="keyword"> const</span>
00668 <span class="keyword"> </span>{ <span class="keywordflow">return</span> !operator==(org); }
00669
00670 base_iterator operator+(size_t n)<span class="keyword"> const</span>
00671 <span class="keyword"> </span>{
00672 base_iterator tmp = *<span class="keyword">this</span>;
00673
00674 <span class="keywordflow">for</span>(;n != 0; --n)
00675 {
00676 ++tmp;
00677 }
00678
00679 <span class="keywordflow">return</span> tmp;
00680 }
00681
00682 base_iterator&amp; operator++(<span class="keywordtype">void</span>)
00683 {
00684 subtree* parent = node-&gt;get_parent();
00685
00686 <span class="keywordflow">if</span> (parent == 0)
00687 {
00688 node = 0;
00689 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00690 }
00691 <span class="comment">// else</span>
00692 <span class="keyword">typename</span> subtree::iterator it;
00693 <span class="keywordflow">for</span> (it = parent-&gt;begin(); it != parent-&gt;end(); ++it)
00694 {
00695 <span class="keywordflow">if</span> (node == &amp;(*it))
00696 <span class="keywordflow">break</span>;
00697 }
00698
00699 <span class="keywordflow">if</span> (it == parent-&gt;begin())
00700 node = parent;
00701 <span class="keywordflow">else</span>
00702 {
00703 node = &amp;(--it)-&gt;get_node(0);
00704 }
00705
00706 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00707 }
00708
00709 base_iterator operator++(<span class="keywordtype">int</span>)
00710 {
00711 base_iterator tmp = *<span class="keyword">this</span>;
00712 operator++();
00713 <span class="keywordflow">return</span> tmp;
00714 }
00715
00716 <span class="keyword">protected</span> :
00717 subtree* node;
00718 };
00719
00720 <span class="keyword">class </span>iterator : <span class="keyword">public</span> base_iterator
00721 {
00722 <span class="keyword">public</span>:
00723
00724 <span class="keyword">using</span> base_iterator::node;
00725
00726 <span class="keyword">typedef</span> std::forward_iterator_tag iterator_category;
00727 <span class="keyword">typedef</span> subtree value_type;
00728 <span class="keyword">typedef</span> size_t distance_type;
00729 <span class="keyword">typedef</span> size_t difference_type;
00730 <span class="keyword">typedef</span> subtree* pointer;
00731 <span class="keyword">typedef</span> subtree&amp; reference;
00732
00733 iterator() : base_iterator() {}
00734 iterator(subtree* n): base_iterator(n) {}
00735 iterator&amp; operator=(<span class="keyword">const</span> iterator&amp; org)
00736 { base_iterator::operator=(org); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00737
00738 subtree&amp; operator*(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> *node; }
00739 subtree* operator-&gt;(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> node; }
00740 };
00741
00742
00743
00744 <span class="keyword">class </span>embedded_iterator : <span class="keyword">public</span> base_iterator
00745 {
00746 <span class="keyword">public</span>:
00747
00748 <span class="keyword">using</span> base_iterator::node;
00749
00750 <span class="keyword">typedef</span> std::forward_iterator_tag iterator_category;
00751 <span class="keyword">typedef</span> T value_type;
00752 <span class="keyword">typedef</span> size_t distance_type;
00753 <span class="keyword">typedef</span> size_t difference_type;
00754 <span class="keyword">typedef</span> T* pointer;
00755 <span class="keyword">typedef</span> T&amp; reference;
00756
00757 embedded_iterator() : base_iterator() {}
00758 embedded_iterator(subtree* n): base_iterator(n) {}
00759 embedded_iterator&amp; operator=(<span class="keyword">const</span> embedded_iterator&amp; org)
00760 { base_iterator::operator=(org); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00761
00762 T&amp; operator*(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> **node; }
00763 T* operator-&gt;(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> &amp;**node; }
00764 };
00765
00766 <span class="keyword">class </span>base_const_iterator
00767 {
00768 <span class="keyword">public</span>:
00769
00770 base_const_iterator() {}
00771 base_const_iterator(<span class="keyword">const</span> subtree* n) { node = n; }
00772
00773 base_const_iterator&amp; operator=(<span class="keyword">const</span> base_const_iterator&amp; org)
00774 { node = org.node; <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00775
00776 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> base_const_iterator&amp; org)<span class="keyword"> const</span>
00777 <span class="keyword"> </span>{ <span class="keywordflow">return</span> node == org.node; }
00778 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> base_const_iterator&amp; org)<span class="keyword"> const</span>
00779 <span class="keyword"> </span>{ <span class="keywordflow">return</span> !operator==(org); }
00780
00781 base_const_iterator&amp; operator++(<span class="keywordtype">void</span>)
00782 {
00783 <span class="keyword">const</span> subtree* parent = node-&gt;get_parent();
00784
00785 <span class="keywordflow">if</span> (parent == 0)
00786 {
00787 node = 0;
00788 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00789 }
00790 <span class="comment">// else</span>
00791 <span class="keyword">typename</span> subtree::const_iterator it;
00792
00793 <span class="keywordflow">for</span> (it = parent-&gt;begin(); it != parent-&gt;end(); ++it)
00794 {
00795 <span class="keywordflow">if</span> (node == &amp;(*it))
00796 <span class="keywordflow">break</span>;
00797 }
00798
00799 <span class="keywordflow">if</span> (it == parent-&gt;begin())
00800 node = parent;
00801 <span class="keywordflow">else</span>
00802 node = &amp;(--it)-&gt;get_node(0);
00803 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00804 }
00805
00806 base_const_iterator operator++(<span class="keywordtype">int</span>)
00807 {
00808 base_const_iterator tmp = *<span class="keyword">this</span>;
00809 operator++();
00810 <span class="keywordflow">return</span> tmp;
00811 }
00812
00813 <span class="keyword">protected</span> :
00814
00815 <span class="keyword">const</span> subtree* node;
00816 };
00817
00818 <span class="keyword">class </span>const_iterator : <span class="keyword">public</span> base_const_iterator
00819 {
00820 <span class="keyword">public</span>:
00821
00822 <span class="keyword">using</span> base_iterator::node;
00823
00824 <span class="keyword">typedef</span> std::forward_iterator_tag iterator_category;
00825 <span class="keyword">typedef</span> <span class="keyword">const</span> subtree value_type;
00826 <span class="keyword">typedef</span> size_t distance_type;
00827 <span class="keyword">typedef</span> size_t difference_type;
00828 <span class="keyword">typedef</span> <span class="keyword">const</span> subtree* pointer;
00829 <span class="keyword">typedef</span> <span class="keyword">const</span> subtree&amp; reference;
00830
00831 const_iterator() : base_const_iterator() {}
00832 const_iterator(<span class="keyword">const</span> subtree* n): base_const_iterator(n) {}
00833 const_iterator&amp; operator=(<span class="keyword">const</span> const_iterator&amp; org)
00834 { base_const_iterator::operator=(org); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00835
00836 <span class="keyword">const</span> subtree&amp; operator*(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> *node; }
00837 <span class="keyword">const</span> subtree* operator-&gt;(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> node; }
00838 };
00839
00840 <span class="keyword">class </span>embedded_const_iterator : <span class="keyword">public</span> base_const_iterator
00841 {
00842 <span class="keyword">public</span>:
00843
00844 <span class="keyword">using</span> base_const_iterator::node;
00845
00846 <span class="keyword">typedef</span> std::forward_iterator_tag iterator_category;
00847 <span class="keyword">typedef</span> <span class="keyword">const</span> T value_type;
00848 <span class="keyword">typedef</span> size_t distance_type;
00849 <span class="keyword">typedef</span> size_t difference_type;
00850 <span class="keyword">typedef</span> <span class="keyword">const</span> T* pointer;
00851 <span class="keyword">typedef</span> <span class="keyword">const</span> T&amp; reference;
00852
00853 embedded_const_iterator() : base_const_iterator() {}
00854 embedded_const_iterator(<span class="keyword">const</span> subtree* n): base_const_iterator(n) {}
00855 embedded_const_iterator&amp; operator=(<span class="keyword">const</span> embedded_const_iterator&amp; org)
00856 { base_const_iterator::operator=(org); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00857
00858 embedded_const_iterator operator+(size_t n)<span class="keyword"> const</span>
00859 <span class="keyword"> </span>{
00860 embedded_const_iterator tmp = *<span class="keyword">this</span>;
00861
00862 <span class="keywordflow">for</span>(;n != 0; --n)
00863 {
00864 ++tmp;
00865 }
00866
00867 <span class="keywordflow">return</span> tmp;
00868 }
00869
00870 <span class="keyword">const</span> T&amp; operator*(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> **node; }
00871 <span class="keyword">const</span> T* operator-&gt;(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> node-&gt;operator-&gt;(); }
00872 };
00873
00874 <span class="comment">/* Iterator access */</span>
00875
00876 iterator begin(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> iterator(&amp;<span class="keyword">operator</span>[](0)); }
00877 const_iterator begin(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(&amp;<span class="keyword">operator</span>[](0)); }
00878 iterator end(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> iterator(0); }
00879 const_iterator end(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> const_iterator(0);}
00880
00881 embedded_iterator ebegin(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> embedded_iterator(&amp;<span class="keyword">operator</span>[](0)); }
00882 embedded_const_iterator ebegin(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> embedded_const_iterator(&amp;<span class="keyword">operator</span>[](0)); }
00883 embedded_iterator eend(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> embedded_iterator(0); }
00884 embedded_const_iterator eend(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> embedded_const_iterator(0);}
00885
00886 <span class="keywordtype">bool</span> empty(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> size() == 0; }
00887 <span class="keywordtype">bool</span> valid(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> pushed.empty(); }
00888
00889 <span class="comment">/* push_back */</span>
00890
00891 <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> parse_tree&lt;T&gt;&amp; tree)
00892 {
00893 <span class="keywordflow">if</span> (!empty())
00894 pushed.push_back(_root);
00895
00896 _root = tree.back();
00897 }
00898
00899 <span class="keywordtype">void</span> push_back(<span class="keyword">const</span> T&amp; t)
00900 {
00901 <span class="keywordflow">if</span> (!empty())
00902 pushed.push_back(_root);
00903
00904 _root = t;
00905
00906 <span class="keywordflow">for</span> (<span class="keyword">typename</span> subtree::iterator it = _root.begin(); it != _root.end(); it++)
00907 {
00908 *it = pushed.back();
00909 pushed.pop_back();
00910 }
00911
00912 }
00913
00914 <span class="comment">/* Access to subtrees */</span>
00915
00916 subtree&amp; back(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> _root; }
00917 <span class="keyword">const</span> subtree&amp; back(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _root; }
00918 subtree&amp; root(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> _root; }
00919 <span class="keyword">const</span> subtree&amp; root(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _root; }
00920
00921 subtree&amp; front(<span class="keywordtype">void</span>) { <span class="keywordflow">return</span> _root[0]; }
00922 <span class="keyword">const</span> subtree&amp; front(<span class="keywordtype">void</span>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> _root[0]; }
00923
00924 subtree&amp; operator[](size_t i)
00925 { <span class="keywordflow">return</span> const_cast&lt;subtree&amp;&gt;(_root.get_node(i)); }
00926 <span class="keyword">const</span> subtree&amp; operator[](size_t i)<span class="keyword"> const</span>
00927 <span class="keyword"> </span>{ <span class="keywordflow">return</span> _root.get_node(i); }
00928
00929 subtree&amp; get_cumulative(size_t i)
00930 { <span class="keywordflow">return</span> const_cast&lt;subtree&amp;&gt;(_root.get_cumulative(i)); }
00931 <span class="keyword">const</span> subtree&amp; get_cumulative(size_t i)<span class="keyword"> const</span>
00932 <span class="keyword"> </span>{ <span class="keywordflow">return</span> get_cumulative(i); }
00933
00934 <span class="keyword">private</span> :
00935
00936 parse_tree&amp; copy(<span class="keyword">const</span> parse_tree&amp; org)
00937 {
00938 _root = org._root;
00939 pushed = org.pushed;
00940
00941 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00942 }
00943
00944 parse_tree&amp; copy(<span class="keyword">const</span> subtree&amp; sub)
00945 { _root = sub; pushed.resize(0); <span class="keywordflow">return</span> *<span class="keyword">this</span>; }
00946
00947 subtree _root;
00948 std::vector&lt;subtree &gt; pushed;
00949 }; <span class="comment">// end class parse_tree</span>
00950
00951
00952 } <span class="comment">// end namespace gp_parse_tree</span>
00953
00954 <span class="keyword">namespace </span>std
00955 { <span class="comment">// for use with stlport on MSVC</span>
00956
00957 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt; <span class="keyword">inline</span>
00958 std::forward_iterator_tag iterator_category(<span class="keyword">typename</span> gp_parse_tree::parse_tree&lt;T&gt;::embedded_iterator)
00959 {
00960 <span class="keywordflow">return</span> std::forward_iterator_tag();
00961 }
00962
00963 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt; <span class="keyword">inline</span>
00964 ptrdiff_t* distance_type(<span class="keyword">typename</span> gp_parse_tree::parse_tree&lt;T&gt;::embedded_iterator)
00965 {
00966 <span class="keywordflow">return</span> 0;
00967 }
00968
00969 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt; <span class="keyword">inline</span>
00970 std::forward_iterator_tag iterator_category(<span class="keyword">typename</span> gp_parse_tree::parse_tree&lt;T&gt;::iterator)
00971 {
00972 <span class="keywordflow">return</span> std::forward_iterator_tag();
00973 }
00974
00975 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt; <span class="keyword">inline</span>
00976 ptrdiff_t* distance_type(<span class="keyword">typename</span> gp_parse_tree::parse_tree&lt;T&gt;::iterator)
00977 {
00978 <span class="keywordflow">return</span> 0;
00979 }
00980
00981 <span class="comment">/* Put customized swaps also in std...</span>
00982 <span class="comment"></span>
00983 <span class="comment">template&lt;class T&gt; inline</span>
00984 <span class="comment">void swap(gp_parse_tree::parse_tree&lt;T&gt;&amp; a, gp_parse_tree::parse_tree&lt;T&gt;&amp; b)</span>
00985 <span class="comment">{</span>
00986 <span class="comment"> a.swap(b);</span>
00987 <span class="comment">}</span>
00988 <span class="comment"></span>
00989 <span class="comment">template&lt;class T&gt; inline</span>
00990 <span class="comment">void iter_swap(std::vector&lt;gp_parse_tree::parse_tree&lt;T&gt; &gt;::iterator a, std::vector&lt;gp_parse_tree::parse_tree&lt;T&gt; &gt; b)</span>
00991 <span class="comment">{</span>
00992 <span class="comment"> a-&gt;swap(*b);</span>
00993 <span class="comment">}*/</span>
00994
00995
00996 } <span class="comment">// namespace std</span>
00997
00998
00999 <span class="preprocessor">#endif</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Thu Oct 19 05:06:41 2006 for EO by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.3.9.1 </small></address>
</body>
</html>