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