00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __SCOPE_HH
00018 # define __SCOPE_HH
00019
00020 # include "../strategies.hh"
00021 # include "../../patterns/variable.hh"
00022
00023 namespace aurelia {
00024
00025 template <typename Strat, typename T>
00026 struct scope_strategy {
00027 private:
00028 Strat s;
00029 T v;
00030
00031 public:
00032 scope_strategy(const Strat& s, const T& v): s(s), v(v) {}
00033 scope_strategy(const scope_strategy& other): s(other.s), v(other.v) {}
00034
00035 template <typename U>
00036 typename strategy_model<Strat, U>::model::output
00037 operator()(const U& t) const {
00038 typedef typename strategy_concept
00039 <typename strategy_model<Strat, U>::model>::check
00040 require;
00041
00042 struct onexit {
00043 const T& v;
00044 onexit(const T& v): v(v) {
00045 v.push();
00046 }
00047 ~onexit() {
00048 v.pop();
00049 }
00050 };
00051 onexit oe(v);
00052 return s(t);
00053 }
00054 };
00055
00056 template <typename Strat, typename T>
00057 scope_strategy<Strat, variable<T> > scope(const variable<T>& v,
00058 const Strat& s) {
00059 return scope_strategy<Strat, variable<T> >(s, v);
00060 }
00061
00062 template <typename T>
00063 struct is_variable: public std::false_type {};
00064
00065 template <typename T>
00066 struct is_variable<variable<T> >: public std::true_type {};
00067
00068 template <typename Strat, typename L,
00069 typename M =
00070 typename list_model<L>::model,
00071 typename = typename
00072 std::enable_if<all_elements<is_variable, L>::value>::type>
00073 scope_strategy<Strat, L>
00074 scope(const L& v, const Strat& s) {
00075 typedef typename list_concept<M>::check require;
00076 return scope_strategy<Strat, L>(s, v);
00077 }
00078 }
00079
00080 #endif