list_terms.hh

00001 // This file is a part of Aurelia.
00002 // Copyright (C) 2010  Valentin David
00003 // Copyright (C) 2010  University of Bergen
00004 //
00005 // This program is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 #ifndef __LIST_TERMS_HH
00018 # define __LIST_TERMS_HH
00019 
00020 # include "term_utils.hh"
00021 # include "../patterns/pattern_utils.hh"
00022 
00023 namespace aurelia {
00024 
00025   template <typename a>
00026   struct list;
00027 
00028   struct cons_constr {};
00029   namespace patterns {
00030     pattern_generator<cons_constr> cons;
00031   }
00032 
00033   template <typename a>
00034   struct get_tuple<list<a>, cons_constr> {
00035     typedef std::tuple<a, list<a> > tuple;
00036   };
00037 
00038   struct nil_constr {};
00039   namespace patterns {
00040     pattern_generator<nil_constr> nil;
00041   }
00042 
00043   template <typename a>
00044   struct get_tuple<list<a>, nil_constr> {
00045     typedef std::tuple<> tuple;
00046   };
00047 
00048   template <typename a>
00049   struct cons_term;
00050 
00051   template <typename a>
00052   struct nil_term;
00053 
00054   template <typename a>
00055   struct list: public term<list<a>, nil_constr, cons_constr> {
00056     typedef term<list<a>, nil_constr, cons_constr> super;
00057     list() = default;
00058     list(const super& other): super(other) {}
00059     list(super&& other): super(std::move(other)) {}
00060   };
00061 
00062   template <typename a>
00063   struct cons_term: public std_term<cons_term<a>, cons_constr, list<a> > {
00064     typedef std_term<cons_term<a>, cons_constr, list<a> > super;
00065     cons_term(a h, const list<a>& t): super(typename super::tuple(h, t)) {}
00066     cons_term(const cons_term& other): super(other) {}
00067   };
00068 
00069   template <typename a>
00070   struct build_type<list<a>, cons_constr> {
00071     typedef cons_term<a> type;
00072   };
00073 
00074   template <typename a>
00075   struct nil_term: public std_term<nil_term<a>, nil_constr, list<a> > {
00076     typedef std_term<nil_term<a>, nil_constr, list<a> > super;
00077     nil_term(): super(typename super::tuple()) {}
00078     nil_term(const nil_term& other): super(other) {}
00079   };
00080 
00081   template <typename a>
00082   struct build_type<list<a>, nil_constr> {
00083     typedef nil_term<a> type;
00084   };
00085 
00086   template <typename a>
00087   struct term_model<list<a> > {
00088     struct model {
00089       typedef list<a> type;
00090     };
00091   };
00092 
00093 }
00094 
00095 #endif