constructor.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 __CONSTRUCTOR_HH
00018 # define __CONSTRUCTOR_HH
00019 
00020 # include <string>
00021 # include "../lists/list_concept.hh"
00022 # include "../lists/listable.hh"
00023 # include "../max_shared/max_shared_ptr.hh"
00024 # include "../memory/pool_allocator.hh"
00025 
00026 namespace aurelia {
00027 
00028   template <typename Pool>
00029   struct untyped_term;
00030 
00031   template <typename Pool, typename List>
00032   struct untyped_pattern;
00033 
00034   template <typename Pool>
00035   struct untyped_constructor;
00036 
00037   template <typename T>
00038   struct pattern_model;
00039 
00040   template <typename Pool, typename T>
00041   struct is_term_traits : public std::false_type {
00042   };
00043 
00044   template <typename Pool>
00045   struct is_term_traits<Pool, untyped_term<Pool> > : public std::true_type {
00046   };
00047 
00048   template <typename Pool>
00049   struct is_term_traits<Pool, untyped_constructor<Pool> > : public std::true_type {
00050   };
00051 
00052   template <typename Pool>
00053   struct is_term {
00054     template <typename T>
00055     struct traits : public is_term_traits<Pool, T> {
00056     };
00057   };
00058 
00059   template <typename Pool, typename T>
00060   struct is_pattern_traits;
00061 
00062   template <typename Pool>
00063   struct is_pattern {
00064     template <typename T>
00065     struct traits: public is_pattern_traits<Pool, T> {
00066     };
00067   };
00068 
00069 struct untyped_constructor_core {
00070 private:
00071   std::string _name;
00072   unsigned _arity;
00073   unsigned _hash;
00074 
00075 public:
00076   untyped_constructor_core(const std::string& n, unsigned a):
00077     _name(n), _arity(a) {
00078     _hash = a;
00079     for (std::string::const_iterator i = n.begin();
00080          i != n.end();
00081          ++i) {
00082       _hash ^= (unsigned char)*i;
00083       _hash = (_hash << 11) | (_hash >> 21);
00084     }
00085   }
00086 
00087   untyped_constructor_core(): _arity(0), _hash(0) {}
00088   untyped_constructor_core(untyped_constructor_core&& other):
00089     _name(""), _arity(0), _hash(0) {
00090     *this = std::move(other);
00091   }
00092 
00093   untyped_constructor_core& operator=(const untyped_constructor_core& other) {
00094     return *this = untyped_constructor_core(other);
00095   }
00096 
00097   untyped_constructor_core& operator=(untyped_constructor_core&& other) {
00098     std::swap(_name, other._name);
00099     std::swap(_arity, other._arity);
00100     std::swap(_hash, other._hash);
00101     return *this;
00102   }
00103 
00104   untyped_constructor_core(const untyped_constructor_core& o)
00105   : _name(o._name), _arity(o._arity), _hash(o._hash) {
00106   }
00107 
00108   unsigned hash() const {
00109     return _hash;
00110   }
00111 
00112   bool operator==(const untyped_constructor_core& other) const {
00113     if (_arity != other._arity)
00114       return false;
00115     return (_name == other._name);
00116   }
00117 
00118   unsigned arity() const {
00119     return _arity;
00120   }
00121 
00122   const std::string& name() const {
00123     return _name;
00124   }
00125 };
00126 
00127   template <typename Pool>
00128   struct untyped_constructor:
00129     public max_shared_ptr<untyped_constructor_core,
00130                           member_hash,
00131                           std::equal_to<untyped_constructor_core>,
00132                           pool_allocator<untyped_constructor_core> > {
00133     typedef max_shared_ptr<untyped_constructor_core,
00134                            member_hash,
00135                            std::equal_to<untyped_constructor_core>,
00136                            pool_allocator<untyped_constructor_core> > super;
00137 
00138   public:
00139     untyped_constructor(): super() {
00140     }
00141 
00142     untyped_constructor(untyped_constructor&& other): super((super&&)std::move(other)) {
00143     }
00144 
00145     untyped_constructor(const untyped_constructor& other): super((const super&)other) {
00146     }
00147 
00148     template <typename OtherPool,
00149               typename =
00150               typename
00151               std::enable_if<!std::is_same<Pool, OtherPool>::value>::type>
00152     untyped_constructor(const untyped_constructor<OtherPool>& other)
00153       : super(other) {
00154     }
00155 
00156     untyped_constructor(const std::string& n, unsigned a)
00157       : super(n, a) {
00158     }
00159 
00160     untyped_constructor(const std::string& n)
00161       : super(n, 0) {
00162     }
00163 
00164     unsigned arity() const {
00165       return (*this)->arity();
00166     }
00167 
00168     const std::string& name() const {
00169       return (*this)->name();
00170     }
00171 
00172     unsigned hash() const {
00173       return (*this)->hash();
00174     }
00175 
00176     static untyped_constructor AS_INT;
00177     static untyped_constructor AS_REAL;
00178     static untyped_constructor AS_BLOB;
00179     static untyped_constructor AS_LIST;
00180     static untyped_constructor AS_EMPTY_LIST;
00181     static untyped_constructor AS_ANNOTATION;
00182 
00183     template <typename L,
00184               typename = typename list_model<L>::model,
00185               template <typename> class Predicate =
00186               is_term<Pool>::template traits,
00187               typename = typename
00188               std::enable_if<all_elements<Predicate, L>::value>::type>
00189     untyped_term<Pool> operator[](const L&) const;
00190 
00191     untyped_term<Pool> operator[](const untyped_term<Pool>& t) const {
00192       return (*this)[list_cons<untyped_term<Pool>, list_nil>(t, list_nil())];
00193     }
00194 
00195     untyped_term<Pool> operator[](const untyped_constructor<Pool>& c) const {
00196       return (*this)[list_cons<untyped_term<Pool>, list_nil>(c, list_nil())];
00197     }
00198 
00199     template <typename P,
00200               typename = typename pattern_model<P>::model>
00201     untyped_pattern<Pool, list_cons<P, list_nil> >
00202     operator[](const P& p) const {
00203       return (*this)[list_cons<P, list_nil>(p, list_nil())];
00204     }
00205 
00206     template <typename L,
00207               typename = typename list_model<L>::model,
00208               template <typename> class untyped_termPredicate =
00209               is_term<Pool>::template traits,
00210               template <typename> class PatternPredicate =
00211               is_pattern<Pool>::template traits,
00212               typename = typename
00213               std::enable_if<!(all_elements<untyped_termPredicate, L>::value)>::type,
00214               typename = typename
00215               std::enable_if<all_elements<PatternPredicate, L>::value>::type>
00216     untyped_pattern<Pool, L> operator[](const L& l) const;
00217   };
00218 
00219   template <typename Pool>
00220   untyped_constructor<Pool> untyped_constructor<Pool>::AS_INT("<int>", 0);
00221   template <typename Pool>
00222   untyped_constructor<Pool> untyped_constructor<Pool>::AS_REAL("<read>", 0);
00223   template <typename Pool>
00224   untyped_constructor<Pool> untyped_constructor<Pool>::AS_BLOB("<blob>", 0);
00225   template <typename Pool>
00226   untyped_constructor<Pool> untyped_constructor<Pool>::AS_LIST("[_,_]", 2);
00227   template <typename Pool>
00228   untyped_constructor<Pool> untyped_constructor<Pool>::AS_EMPTY_LIST("[]",0);
00229   template <typename Pool>
00230   untyped_constructor<Pool> untyped_constructor<Pool>::AS_ANNOTATION("{}",2);
00231 
00232   template <typename Stream, typename Pool>
00233   Stream& operator<<(Stream& s, const untyped_constructor<Pool>& t) {
00234     s << t.name() << "(" << t.arity() << ")";
00235     return s;
00236   }
00237 
00238   template <typename Pool>
00239   struct listable_model<untyped_constructor<Pool> > {
00240     struct model {
00241       typedef untyped_constructor<Pool> type;
00242     };
00243   };
00244 
00245 }
00246 
00247 #endif