00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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