map.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 __MAP_HH
00018 # define __MAP_HH
00019 
00020 # include "../strategies.hh"
00021 # include <bitset>
00022 
00023 namespace aurelia {
00024 
00027   template <typename S>
00028   struct map_strategy {
00029     S s;
00030     map_strategy(const S& s): s(s) {
00031     }
00032 
00033     template <int N>
00034     std::bitset<N> operator()(std::bitset<N> t) const {
00035       typedef typename
00036         strategy_concept<typename strategy_model<S, typename std::bitset<N>
00037                                                  ::value_type>::model>
00038         ::check require;
00039 
00040       for (unsigned i = 0; i < N; ++i) {
00041         t[i] = s(t[i]);
00042       }
00043       return t;
00044     }
00045 
00046     template <typename T,
00047               typename M =
00048               typename strategy_model<S, typename T::value_type>::model>
00049     T operator()(const T& t) const {
00050       typedef typename strategy_concept<M>::check require;
00051 
00052       T ret;
00053       for (typename T::const_iterator i = t.begin(); i != t.end(); ++i)
00054         ret.insert(ret.end(), s(*i));
00055       return ret;
00056     }
00057 
00058     template <typename Pool,
00059               typename M = typename
00060               strategy_model<S, untyped_term<Pool> >::model>
00061     untyped_term<Pool> operator()(const untyped_term<Pool>& t) const {
00062       typedef typename strategy_concept<M>::check require;
00063 
00064       typedef untyped_term<Pool> T;
00065       typedef untyped_constructor<Pool> C;
00066 
00067       try {
00068         if (t.constructor() != C::AS_EMPTY_LIST)
00069           throw failure();
00070         return t;
00071       } catch (failure) {
00072         if (t.constructor() == C::AS_LIST) {
00073           T a = s(t[0]);
00074           T b = (*this)(t[1]);
00075           return T(C::AS_LIST, (a, b));
00076         } else
00077           throw failure();
00078       }
00079     }
00080   };
00081 
00085   template <typename S>
00086   map_strategy<S> map(const S& s) {
00087     return map_strategy<S>(s);
00088   }
00089 
00090 }
00091 
00092 #endif