1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef SANDBOX_LINUX_BPF_DSL_CONS_H_
6 #define SANDBOX_LINUX_BPF_DSL_CONS_H_
8 #include "base/memory/ref_counted.h"
9 #include "sandbox/sandbox_export.h"
14 // Namespace cons provides an abstraction for immutable "cons list"
15 // data structures as commonly provided in functional programming
16 // languages like Lisp or Haskell.
18 // A cons list is a linked list consisting of "cells", each of which
19 // have a "head" and a "tail" element. A cell's head element contains
20 // a user specified value, while the tail element contains a (possibly
21 // null) pointer to another cell.
23 // An empty list (idiomatically referred to as "nil") can be
24 // constructed as "cons::List<Foo>()" or simply as "nullptr" if Foo
25 // can be inferred from context (e.g., calling a function that has a
26 // "cons::List<Foo>" parameter).
28 // Existing lists (including empty lists) can be extended by
29 // prepending new values to the front using the "Cons(head, tail)"
30 // function, which will allocate a new cons cell. Notably, cons lists
31 // support creating multiple lists that share a common tail sequence.
33 // Lastly, lists support iteration via C++11's range-based for loop
38 // // basic construction
39 // const cons::List<char> kNil = nullptr;
40 // cons::List<char> ba = Cons('b', Cons('a', kNil));
42 // // common tail sequence
43 // cons::List<char> cba = Cons('c', ba);
44 // cons::List<char> dba = Cons('d', ba);
47 // for (const char& ch : cba) {
48 // // iterates 'c', 'b', 'a'
50 // for (const char& ch : dba) {
51 // // iterates 'd', 'b', 'a'
54 // Forward declarations.
60 // List represents a (possibly null) pointer to a cons cell.
62 using List
= scoped_refptr
<const Cell
<T
>>;
64 // Cons extends a cons list by prepending a new value to the front.
66 List
<T
> Cons(const T
& head
, const List
<T
>& tail
) {
67 return List
<T
>(new const Cell
<T
>(head
, tail
));
70 // Cell represents an individual "cons cell" within a cons list.
72 class Cell
: public base::RefCounted
<Cell
<T
>> {
74 Cell(const T
& head
, const List
<T
>& tail
) : head_(head
), tail_(tail
) {}
76 // Head returns this cell's head element.
77 const T
& head() const { return head_
; }
79 // Tail returns this cell's tail element.
80 const List
<T
>& tail() const { return tail_
; }
88 friend class base::RefCounted
<Cell
<T
>>;
89 DISALLOW_COPY_AND_ASSIGN(Cell
);
92 // Begin returns a list iterator pointing to the first element of the
93 // cons list. It's provided to support range-based for loops.
95 ListIterator
<T
> begin(const List
<T
>& list
) {
96 return ListIterator
<T
>(list
);
99 // End returns a list iterator pointing to the "past-the-end" element
100 // of the cons list (i.e., nil). It's provided to support range-based
102 template <typename T
>
103 ListIterator
<T
> end(const List
<T
>& list
) {
104 return ListIterator
<T
>();
107 // ListIterator provides C++ forward iterator semantics for traversing
109 template <typename T
>
112 ListIterator() : list_() {}
113 explicit ListIterator(const List
<T
>& list
) : list_(list
) {}
115 const T
& operator*() const { return list_
->head(); }
117 ListIterator
& operator++() {
118 list_
= list_
->tail();
122 friend bool operator==(const ListIterator
& lhs
, const ListIterator
& rhs
) {
123 return lhs
.list_
== rhs
.list_
;
130 template <typename T
>
131 bool operator!=(const ListIterator
<T
>& lhs
, const ListIterator
<T
>& rhs
) {
132 return !(lhs
== rhs
);
136 } // namespace sandbox
138 #endif // SANDBOX_LINUX_BPF_DSL_CONS_H_