/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev$ $Date$ */ #ifndef tuscany_list_hpp #define tuscany_list_hpp /** * Simple list functions. */ #include #include "function.hpp" namespace tuscany { long countlists = 0; long countIlists = 0; long countClists = 0; long countElists = 0; bool resetlistCounters() { countlists = countIlists = countClists = countElists = 0; return true; } bool printlistCounters() { std::cout << "countlists " << countlists << std::endl; std::cout << "countElists " << countElists << std::endl; std::cout << "countIlists " << countIlists << std::endl; std::cout << "countClists " << countClists << std::endl; return true; } /** * A car/cdr lisp-like pair, base structure to construct lists. */ template class list { public: list(const T car, const lambda ()>& cdr) : nil(false), car(car), cdr(cdr) { countlists++; countIlists++; } list() : nil(true) { countlists++; countElists++; } list(const list& p) : nil(p.nil), car(p.car), cdr(p.cdr) { countlists++; countClists++; } const list& operator=(const list& p) { if(this == &p) return *this; nil = p.nil; car = p.car; cdr = p.cdr; return *this; } ~list() { countlists--; } const bool operator==(const list& p) const { if(this == &p) return true; if(nil) return p.nil; if(p.nil) return false; if(!(car == p.car)) return false; if(cdr == p.cdr) return true; return cdr() == p.cdr(); } const bool operator!=(const list& p) const { return !this->operator==(p); } template friend std::ostream& operator<<(std::ostream&, const list&); bool nil; T car; lambda ()> cdr; }; /** * Returns true if the given list is nil. */ template const bool isNil(const list& p) { return p.nil; } /** * Write a list to an output stream. */ template std::ostream& operator<<(std::ostream& out, const list& l) { if(l == list ()) return out << "()"; return out << "(" << car(l) << ", " << cdr(l) << ")"; } /** * Construct a (lazy) list from a value and a lambda function that returns the cdr. */ template const list cons(const T& car, const lambda ()>& cdr) { return list (car, cdr); } /** * Construct a list from a value and a cdr list. */ template const list cons(const T& car, const list& cdr) { return list (car, unit(cdr)); } /** * Construct a list of one value. */ template const list makeList(const T& car) { return list (car, unit(list ())); } /** * Construct a list of two values. */ template const list makeList(const T& a, const T& b) { return cons(a, makeList(b)); } /** * Construct a list of three values. */ template const list makeList(const T& a, const T& b, const T& c) { return cons(a, cons(b, makeList(c))); } /** * Construct a list of four values. */ template const list makeList(const T& a, const T& b, const T& c, const T& d) { return cons(a, cons(b, cons(c, makeList(d)))); } /** * Returns the car of a list. */ template const T car(const list& p) { return p.car; } /** * Returns the cdr of a list. */ template list const cdr(const list& p) { return p.cdr(); } /** * Returns the car of the cdr of a list. */ template const T cadr(const list& p) { return car(cdr(p)); } /** * Returns the car of the cdr of the cdr of a list. */ template const T caddr(const list& p) { return car(cdr(cdr(p))); } /** * Returns the cdr of a cdr of a list. */ template const list cddr(const list& p) { return cdr(cdr(p)); } /** * Returns the cdr of a cdr of the cdr of a list. */ template const list cdddr(const list& p) { return cdr(cdr(cdr(p))); } /** * Returns the length of a list. */ template struct lengthRef { const int operator()(const int c, const list& p) { if(isNil(p)) return c; return (*this)(c + 1, cdr(p)); } }; template const int length(const list& p) { return lengthRef ()(0, p); } /** * Appends a list and a lambda function returning a list. */ template struct appendCdr { const list a; const lambda ()> fb; appendCdr(const list& a, const lambda ()>& fb) : a(a), fb(fb) { } const list operator()() const { return append(a, fb); } }; template const list append(const list&a, const lambda ()>& fb) { if(isNil(a)) return fb(); return cons(car(a), lambda ()> (appendCdr (cdr(a), fb))); } /** * Appends two lists. */ template const list append(const list&a, const list& b) { return append(a, unit(b)); } /** * Map a lambda function on a list. */ template const list map(const lambda& f, const list& p) { if(isNil(p)) return list (); return cons(f(car(p)), map(f, cdr(p))); } /** * Run a reduce lambda function on a list. */ template struct reduceAccumulate { const lambda f; explicit reduceAccumulate(const lambda& f) : f(f) { } R operator()(const R& acc, const list& p) const { if(isNil(p)) return acc; return (*this)(f(acc, car(p)), cdr(p)); } }; template const R reduce(const lambda& f, const R& initial, const list& p) { return reduceAccumulate (f)(initial, p); } /** * Run a filter lambda function on a list. */ template const list filter(const lambda& f, const list& p) { if(isNil(p)) return list (); if(f(car(p))) { const lambda (lambda , list )> ff(filter ); return cons(car(p), curry(ff, f, cdr(p))); } return filter(f, cdr(p)); } /** * Returns a list pointing to a member of a list. */ template const list member(const T& t, const list& p) { if(isNil(p)) return list (); if(t == car(p)) return p; return member(t, cdr(p)); } /** * Reverse a list. */ template const list reverseIter(const list& acc, const list& p) { if(isNil(p)) return acc; return reverseIter(cons(car(p), acc), cdr(p)); } template const list reverse(const list& p) { return reverseIter(list (), p); } template const list seq(const T& start, const T& end); template struct seqGenerate { const T start; const T end; seqGenerate(const T& start, const T&end) : start(start), end(end) { } const list operator()() const { return seq (start, end); } }; /** * Returns a sequence of values between the given bounds. */ template const list seq(const T& start, const T& end) { if(start == end) return makeList(start); if(start < end) return cons(start, lambda ()> (seqGenerate (start + 1, end))); return cons(start, lambda ()> (seqGenerate (start - 1, end))); } /** * Equivalent of the list assoc function. */ template const list assoc(const T& k, const list >& p) { if(isNil(p)) return list (); if(k == car(car(p))) return car(p); return assoc(k, cdr(p)); } /** * Pretty print a list. */ template std::ostream& print(const list& l, std::ostream& os) { os << "("; if (!isNil(l)) { list ml = l; while(true) { os << car(ml); ml = cdr(ml); if (isNil(ml)) break; os << ", "; } } os << ")"; return os; } } #endif /* tuscany_list_hpp */