strategies.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 __STRATEGIES_HH
00018 # define __STRATEGIES_HH
00019 
00020 # include <type_traits/is_callable_with.hh>
00021 # include <functional>
00022 
00023 namespace aurelia {
00024 
00030   template <typename Model>
00031   struct strategy_concept: public Model {
00032   public:
00033     typedef typename Model::strat strat;
00034     typedef typename Model::input input;
00035     typedef typename Model::output output;
00036 #ifdef DOC_GEN
00037 
00038     output operator()(strat, input);
00039 #else
00040     typedef void check;
00041   private:
00042     static_assert(std::is_same<decltype(std::declval<strat>()
00043                                         (std::declval<input>())),
00044                   output>::value,
00045                   "operator() does not return the right type");
00046 #endif
00047   };
00053   template <typename S, typename I>
00054   struct default_strategy_model {
00055     typedef S strat;
00056     typedef I input;
00057     typedef decltype(std::declval<const strat>()(std::declval<input>())) output;
00058   };
00059 
00060   template <typename S, typename I,
00061             bool = type_traits::is_callable_with<const S, I>::value>
00062   struct strategy_model;
00063 
00064   template <typename S, typename I>
00065   struct strategy_model<S, I, false> {
00066     typedef void no_model;
00067   };
00068 
00071   template <typename S, typename I>
00072   struct strategy_model<S, I, true> {
00073     typedef default_strategy_model<S, I> model;
00074   };
00075 
00078   template <typename R, typename ArgType>
00079   struct strategy_model<std::function<R(ArgType)>, ArgType, false> {
00080     struct model {
00081       typedef typename
00082       strategy_concept<strategy_model<std::function<R(ArgType)>,
00083                                       ArgType> >::model require;
00084       typedef std::function<R(ArgType)> strat;
00085       typedef ArgType input;
00086       typedef R output;
00087     };
00088   };
00091 }
00092 
00093 # include "generic/id.hh"
00094 # include "generic/fail.hh"
00095 # include "traversals/all.hh"
00096 # include "generic/choice.hh"
00097 # include "generic/seq.hh"
00098 # include "patterns/match.hh"
00099 # include "patterns/build.hh"
00100 # include "generic/not.hh"
00101 # include "generic/where.hh"
00102 
00127 #endif