00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __ONE_HH
00018 # define __ONE_HH
00019
00020 # include "../../terms/term.hh"
00021 # include "../strategies.hh"
00022
00023 namespace aurelia {
00024
00027 template <typename Strat>
00028 struct one_strategy {
00029 private:
00030 Strat s;
00031 public:
00032 one_strategy(const Strat& s): s(s) {
00033 }
00034
00035 template <typename T>
00036 T operator()(const T& term) const {
00037 unsigned arity = term.constructor().arity();
00038 if (arity > 0) {
00039 for (unsigned i = 0;
00040 i < arity;
00041 ++i) {
00042 try {
00043 T success = s(term[i]);
00044 if (diff_no_conv(success, term[i])) {
00045 return term;
00046 }
00047 T *list = (T*)malloc(arity
00048 *sizeof(T));
00049 for (unsigned j = 0; j < arity; ++j) {
00050 if (j == i)
00051 new (list+j) T(success);
00052 else
00053 new (list+j) T(term[j]);
00054 }
00055 return T(term.constructor(), list);
00056 } catch (failure) {
00057 }
00058 }
00059 throw failure();
00060 }
00061 else
00062 throw failure();
00063 }
00064 };
00065
00069 template <typename Strat>
00070 one_strategy<Strat> one(const Strat& s) {
00071 return one_strategy<Strat>(s);
00072 }
00073
00074 }
00075
00076 #endif