Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 88fb78d

Browse files
Merge pull request #40 from justinmeiners/39-list-examples
add example of how to use list pool
2 parents 1779640 + 88c67b1 commit 88fb78d

File tree

7 files changed

+102
-15
lines changed

7 files changed

+102
-15
lines changed

‎08_lisp.html

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,10 @@ <h3>Free list helper</h3>
396396
}
397397
</code></pre>
398398

399+
<p><strong>Exercise:</strong> Before moving on, get familiar with these operations.
400+
Create a simple list inside a pool and print it by iterating through its contents
401+
(solved in <code>test_list_pool.cpp</code> at the end of the chapter).</p>
402+
399403
<a name="List-queue"></a>
400404
<h2>List queue</h2>
401405

@@ -413,14 +417,6 @@ <h2>List queue</h2>
413417
pair_type empty_queue() { return pair_type(end(), end()); }
414418
</code></pre>
415419

416-
<p>You can remove an element from the front of the queue:</p>
417-
418-
<pre><code>pair_type pop_front(const pair_type&amp; p) {
419-
if (empty(p)) return p;
420-
return pair_type(next(p.first), p.second);
421-
}
422-
</code></pre>
423-
424420
<p>You can add an element to the front, or the back of the queue:</p>
425421

426422
<pre><code>pair_type push_front(const pair_type&amp; p, const T&amp; value) {
@@ -437,6 +433,14 @@ <h2>List queue</h2>
437433
}
438434
</code></pre>
439435

436+
<p>You can remove an element from the front of the queue<sup id="fnref:9"><a href="#fn:9" rel="footnote">9</a></sup>:</p>
437+
438+
<pre><code>pair_type pop_front(const pair_type&amp; p) {
439+
if (empty(p)) return p;
440+
return pair_type(next(p.first), p.second);
441+
}
442+
</code></pre>
443+
440444
<p>Now we can also free lists in constant time,
441445
simply by attaching the end of our list to the free list.</p>
442446

@@ -449,6 +453,7 @@ <h2>Code</h2>
449453
<ul>
450454
<li><a href="code/list_pool.h">list_pool.h</a></li>
451455
<li><a href="code/list_pool_iterator.h">list_pool_iterator.h</a> (included by <code>list_pool.h</code>, but not discussed until Chapter 9)</li>
456+
<li><a href="code/test_list_pool.cpp">test_list_pool.cpp</a></li>
452457
</ul>
453458

454459
<div class="footnotes">
@@ -552,6 +557,13 @@ <h2>Code</h2>
552557
<li id="fn:8">
553558
The assignment in this code is the same as <code>(setf (cdr x) free-list)</code> in Common Lisp,
554559
or <code>(set-cdr! x free-list)</code> in Scheme.<a href="#fnref:8" rev="footnote">&#8617;</a></li>
560+
<li id="fn:9">
561+
Since we implement <code>pop_front</code>, you might also expect <code>pop_back</code>.
562+
A little thought will reveal there is no constant
563+
time implementation for singly linked lists.
564+
The queue has a reference to the last node in the queue,
565+
but removing it would require modification
566+
of the preceding node.<a href="#fnref:9" rev="footnote">&#8617;</a></li>
555567
</ol>
556568
</div>
557569

‎08_lisp.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,10 @@ not just a node.
355355
while (!pool.is_empty(x)) x = pool.free(x);
356356
}
357357

358+
**Exercise:** Before moving on, get familiar with these operations.
359+
Create a simple list inside a pool and print it by iterating through its contents
360+
(solved in `test_list_pool.cpp` at the end of the chapter).
361+
358362

359363
[^rplaca-explanation]: `rplaca` and `rplacd` are unfriendly abbrevations of
360364
"replace car" and "replace cdr" (see "Lisp 1.5 Programmer's Manual").
@@ -383,13 +387,6 @@ and construct them:
383387
bool empty(const pair_type& p) { return is_end(p.first); }
384388
pair_type empty_queue() { return pair_type(end(), end()); }
385389

386-
You can remove an element from the front of the queue:
387-
388-
pair_type pop_front(const pair_type& p) {
389-
if (empty(p)) return p;
390-
return pair_type(next(p.first), p.second);
391-
}
392-
393390
You can add an element to the front, or the back of the queue:
394391

395392
pair_type push_front(const pair_type& p, const T& value) {
@@ -405,13 +402,29 @@ You can add an element to the front, or the back of the queue:
405402
return pair_type(p.first, new_node);
406403
}
407404

405+
You can remove an element from the front of the queue[^no-pop-back]:
406+
407+
pair_type pop_front(const pair_type& p) {
408+
if (empty(p)) return p;
409+
return pair_type(next(p.first), p.second);
410+
}
411+
408412
Now we can also free lists in constant time,
409413
simply by attaching the end of our list to the free list.
410414

411415
void free(const pair_type& p) { free(p.first, p.second); }
412416

413417

418+
[^no-pop-back]: Since we implement `pop_front`, you might also expect `pop_back`.
419+
A little thought will reveal there is no constant
420+
time implementation for singly linked lists.
421+
The queue has a reference to the last node in the queue,
422+
but removing it would require modification
423+
of the preceding node.
424+
425+
414426
## Code
415427

416428
- [list_pool.h](code/list_pool.h)
417429
- [list_pool_iterator.h](code/list_pool_iterator.h) (included by `list_pool.h`, but not discussed until Chapter 9)
430+
- [test_list_pool.cpp](code/test_list_pool.cpp)

‎09_iterators.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,10 @@ <h3>Equality</h3>
422422
When you took Algebra in grade school,
423423
they used <code>=</code> and they used <code>x</code> and <code>y</code> and I think it&rsquo;s good.</p>
424424

425+
<p><strong>Exercise:</strong> Experiment with list pool iterators by using
426+
a standard library algorithm on them, such as <code>find</code> or <code>copy</code>
427+
(see <code>test_list_pool_iterator.cpp</code> at the end of the chapter).</p>
428+
425429
<a name="Thoughts-about-iterator-design"></a>
426430
<h2>Thoughts about iterator design</h2>
427431

@@ -532,6 +536,7 @@ <h2>Code</h2>
532536

533537
<ul>
534538
<li><a href="code/list_pool_iterator.h">list_pool_iterator.h</a></li>
539+
<li><a href="code/test_list_pool_iterator.cpp">test_list_pool_iterator.cpp</a></li>
535540
</ul>
536541

537542
<div class="footnotes">

‎09_iterators.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ for equality, as it violates mathematical tradition.
351351
But, oh well.
352352
When you took Algebra in grade school,
353353
they used `=` and they used `x` and `y` and I think it's good.
354+
355+
**Exercise:** Experiment with list pool iterators by using
356+
a standard library algorithm on them, such as `find` or `copy`
357+
(see `test_list_pool_iterator.cpp` at the end of the chapter).
354358

355359
## Thoughts about iterator design
356360

@@ -478,3 +482,4 @@ A total ordering does not have to be topologically induced by the traversal.
478482
## Code
479483

480484
- [list_pool_iterator.h](code/list_pool_iterator.h)
485+
- [test_list_pool_iterator.cpp](code/test_list_pool_iterator.cpp)

‎code/index.html

Whitespace-only changes.

‎code/test_list_pool.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <iostream>
2+
#include <stdint.h>
3+
#include "list_pool.h"
4+
5+
int main() {
6+
typedef typename list_pool<char, uint16_t>::list_type L;
7+
8+
list_pool<char, uint16_t> pool;
9+
10+
// Create a list "a b c",
11+
// same as Lisp (cons a (cons b (cons c '()))).
12+
L l = pool.end();
13+
l = pool.allocate('c', l);
14+
l = pool.allocate('b', l);
15+
l = pool.allocate('a', l);
16+
17+
// Print contents of list.
18+
L current = l;
19+
while (current != pool.end()) {
20+
std::cout << pool.value(current) << " ";
21+
current = pool.next(current);
22+
}
23+
std::cout << std::endl;
24+
25+
// Pool will cleanup automatically when out of scope.
26+
// But, let's go ahead and test free.
27+
free_list(pool, current);
28+
}
29+

‎code/test_list_pool_iterator.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <iostream>
2+
#include <iterator>
3+
#include <stdint.h>
4+
#include "list_pool.h"
5+
6+
int main() {
7+
typedef typename list_pool<char, uint16_t>::iterator I;
8+
9+
list_pool<char, uint16_t> pool;
10+
11+
// Create a list "a b c",
12+
// same as Lisp (cons a (cons b (cons c '()))).
13+
I last(pool);
14+
I first = last;
15+
push_front(first, 'c');
16+
push_front(first, 'b');
17+
push_front(first, 'a');
18+
19+
// Print contents of list.
20+
std::copy(first, last, std::ostream_iterator<char>(std::cout, " "));
21+
}
22+
23+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /