seq.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 __SEQ_HH
00018 # define __SEQ_HH
00019 
00020 # include "../strategies.hh"
00021 
00022 namespace aurelia {
00023 
00024   template <typename Strat1, typename Strat2>
00025   struct seq_strategy;
00026 
00030   template <typename Strat1, typename Strat2, typename T>
00031   struct strategy_model<seq_strategy<Strat1, Strat2>, T, false> {
00032     struct model {
00033       typedef typename strategy_model<Strat1, T>::model model1;
00034       typedef typename strategy_model<Strat2, typename model1::output>::model
00035       model2;
00036 
00037       typedef typename strategy_concept<model1>::check require1;
00038       typedef typename strategy_concept<model2>::check require2;
00039 
00040       typedef seq_strategy<Strat1, Strat2> strat;
00041       typedef T input;
00042       typedef typename model2::output output;
00043     };
00044   };
00045 
00048   template <typename Strat1, typename Strat2>
00049   struct seq_strategy {
00050   private:
00051     Strat1 s1;
00052     Strat2 s2;
00053   public:
00054     seq_strategy(const Strat1& s1, const Strat2& s2): s1(s1), s2(s2) {
00055     }
00056 
00057     template <typename T>
00058     typename strategy_model<seq_strategy<Strat1, Strat2>, T>::model::output
00059     operator()(const T& term) const {
00060       return s2(s1(term));
00061     }
00062   };
00063 
00068   template <typename Strat1, typename Strat2>
00069   seq_strategy<Strat1, Strat2> operator<(const Strat1& s1, const Strat2& s2) {
00070     return seq_strategy<Strat1, Strat2>(s1, s2);
00071   }
00072 
00073 }
00074 
00075 #endif