cons.h revision 59c5f4b0fb104e8e4806e4934a3d5d112ad695ab
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. 4 5#ifndef SANDBOX_LINUX_BPF_DSL_CONS_H_ 6#define SANDBOX_LINUX_BPF_DSL_CONS_H_ 7 8#include "base/memory/ref_counted.h" 9#include "sandbox/sandbox_export.h" 10 11namespace sandbox { 12namespace cons { 13 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. 17// 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. 22// 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). 27// 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. 32// 33// Lastly, lists support iteration via C++11's range-based for loop 34// construct. 35// 36// Examples: 37// 38// // basic construction 39// const cons::List<char> kNil = nullptr; 40// cons::List<char> ba = Cons('b', Cons('a', kNil)); 41// 42// // common tail sequence 43// cons::List<char> cba = Cons('c', ba); 44// cons::List<char> dba = Cons('d', ba); 45// 46// // iteration 47// for (const char& ch : cba) { 48// // iterates 'c', 'b', 'a' 49// } 50// for (const char& ch : dba) { 51// // iterates 'd', 'b', 'a' 52// } 53 54// Forward declarations. 55template <typename T> 56class Cell; 57template <typename T> 58class ListIterator; 59 60// List represents a (possibly null) pointer to a cons cell. 61template <typename T> 62using List = scoped_refptr<const Cell<T>>; 63 64// Cons extends a cons list by prepending a new value to the front. 65template <typename T> 66List<T> Cons(const T& head, const List<T>& tail) { 67 return List<T>(new const Cell<T>(head, tail)); 68} 69 70// Cell represents an individual "cons cell" within a cons list. 71template <typename T> 72class Cell : public base::RefCounted<Cell<T>> { 73 public: 74 Cell(const T& head, const List<T>& tail) : head_(head), tail_(tail) {} 75 76 // Head returns this cell's head element. 77 const T& head() const { return head_; } 78 79 // Tail returns this cell's tail element. 80 const List<T>& tail() const { return tail_; } 81 82 private: 83 virtual ~Cell() {} 84 85 T head_; 86 List<T> tail_; 87 88 friend class base::RefCounted<Cell<T>>; 89 DISALLOW_COPY_AND_ASSIGN(Cell); 90}; 91 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. 94template <typename T> 95ListIterator<T> begin(const List<T>& list) { 96 return ListIterator<T>(list); 97} 98 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 101// for loops. 102template <typename T> 103ListIterator<T> end(const List<T>& list) { 104 return ListIterator<T>(); 105} 106 107// ListIterator provides C++ forward iterator semantics for traversing 108// a cons list. 109template <typename T> 110class ListIterator { 111 public: 112 ListIterator() : list_() {} 113 explicit ListIterator(const List<T>& list) : list_(list) {} 114 115 const T& operator*() const { return list_->head(); } 116 117 ListIterator& operator++() { 118 list_ = list_->tail(); 119 return *this; 120 } 121 122 friend bool operator==(const ListIterator& lhs, const ListIterator& rhs) { 123 return lhs.list_ == rhs.list_; 124 } 125 126 private: 127 List<T> list_; 128}; 129 130template <typename T> 131bool operator!=(const ListIterator<T>& lhs, const ListIterator<T>& rhs) { 132 return !(lhs == rhs); 133} 134 135} // namespace cons 136} // namespace sandbox 137 138#endif // SANDBOX_LINUX_BPF_DSL_CONS_H_ 139