| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SANDBOX_LINUX_BPF_DSL_CONS_H_ |
| #define SANDBOX_LINUX_BPF_DSL_CONS_H_ |
| |
| #include "base/memory/ref_counted.h" |
| #include "sandbox/sandbox_export.h" |
| |
| namespace sandbox { |
| namespace cons { |
| |
| // Namespace cons provides an abstraction for immutable "cons list" |
| // data structures as commonly provided in functional programming |
| // languages like Lisp or Haskell. |
| // |
| // A cons list is a linked list consisting of "cells", each of which |
| // have a "head" and a "tail" element. A cell's head element contains |
| // a user specified value, while the tail element contains a (possibly |
| // null) pointer to another cell. |
| // |
| // An empty list (idiomatically referred to as "nil") can be |
| // constructed as "cons::List<Foo>()" or simply as "nullptr" if Foo |
| // can be inferred from context (e.g., calling a function that has a |
| // "cons::List<Foo>" parameter). |
| // |
| // Existing lists (including empty lists) can be extended by |
| // prepending new values to the front using the "Cons(head, tail)" |
| // function, which will allocate a new cons cell. Notably, cons lists |
| // support creating multiple lists that share a common tail sequence. |
| // |
| // Lastly, lists support iteration via C++11's range-based for loop |
| // construct. |
| // |
| // Examples: |
| // |
| // // basic construction |
| // const cons::List<char> kNil = nullptr; |
| // cons::List<char> ba = Cons('b', Cons('a', kNil)); |
| // |
| // // common tail sequence |
| // cons::List<char> cba = Cons('c', ba); |
| // cons::List<char> dba = Cons('d', ba); |
| // |
| // // iteration |
| // for (const char& ch : cba) { |
| // // iterates 'c', 'b', 'a' |
| // } |
| // for (const char& ch : dba) { |
| // // iterates 'd', 'b', 'a' |
| // } |
| |
| // Forward declarations. |
| template <typename T> |
| class Cell; |
| template <typename T> |
| class ListIterator; |
| |
| // List represents a (possibly null) pointer to a cons cell. |
| template <typename T> |
| using List = scoped_refptr<const Cell<T>>; |
| |
| // Cons extends a cons list by prepending a new value to the front. |
| template <typename T> |
| List<T> Cons(const T& head, const List<T>& tail) { |
| return List<T>(new const Cell<T>(head, tail)); |
| } |
| |
| // Cell represents an individual "cons cell" within a cons list. |
| template <typename T> |
| class Cell : public base::RefCounted<Cell<T>> { |
| public: |
| Cell(const T& head, const List<T>& tail) : head_(head), tail_(tail) {} |
| |
| // Head returns this cell's head element. |
| const T& head() const { return head_; } |
| |
| // Tail returns this cell's tail element. |
| const List<T>& tail() const { return tail_; } |
| |
| private: |
| virtual ~Cell() {} |
| |
| T head_; |
| List<T> tail_; |
| |
| friend class base::RefCounted<Cell<T>>; |
| DISALLOW_COPY_AND_ASSIGN(Cell); |
| }; |
| |
| // Begin returns a list iterator pointing to the first element of the |
| // cons list. It's provided to support range-based for loops. |
| template <typename T> |
| ListIterator<T> begin(const List<T>& list) { |
| return ListIterator<T>(list); |
| } |
| |
| // End returns a list iterator pointing to the "past-the-end" element |
| // of the cons list (i.e., nil). It's provided to support range-based |
| // for loops. |
| template <typename T> |
| ListIterator<T> end(const List<T>& list) { |
| return ListIterator<T>(); |
| } |
| |
| // ListIterator provides C++ forward iterator semantics for traversing |
| // a cons list. |
| template <typename T> |
| class ListIterator { |
| public: |
| ListIterator() : list_() {} |
| explicit ListIterator(const List<T>& list) : list_(list) {} |
| |
| const T& operator*() const { return list_->head(); } |
| |
| ListIterator& operator++() { |
| list_ = list_->tail(); |
| return *this; |
| } |
| |
| friend bool operator==(const ListIterator& lhs, const ListIterator& rhs) { |
| return lhs.list_ == rhs.list_; |
| } |
| |
| private: |
| List<T> list_; |
| }; |
| |
| template <typename T> |
| bool operator!=(const ListIterator<T>& lhs, const ListIterator<T>& rhs) { |
| return !(lhs == rhs); |
| } |
| |
| } // namespace cons |
| } // namespace sandbox |
| |
| #endif // SANDBOX_LINUX_BPF_DSL_CONS_H_ |