00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __VARIABLE_HH
00018 # define __VARIABLE_HH
00019
00020 # include "pattern.hh"
00021 # include <memory>
00022 # include <stack>
00023 # include "../lists/listable.hh"
00024
00025 namespace aurelia {
00026
00027 template <typename T>
00028 struct variable {
00029 private:
00030 std::shared_ptr<std::stack<std::auto_ptr<T> > > value;
00031
00032 public:
00033
00034 variable(): value(new std::stack<std::auto_ptr<T> >()) {
00035 value->push(std::auto_ptr<T>(NULL));
00036 }
00037
00038 variable(const variable& v): value(v.value) {
00039 }
00040
00041 variable(const T& v): value(new std::stack<std::auto_ptr<T> >()) {
00042 value->push(std::auto_ptr<T>(new T(v)));
00043 }
00044
00045 void push() const {
00046 value->push(std::auto_ptr<T>(NULL));
00047 }
00048
00049 void pop() const {
00050 value->pop();
00051 }
00052
00053 bool has_value() const {
00054 return value->top().get() != NULL;
00055 }
00056
00057 const T& operator*() const {
00058 if (!has_value())
00059 throw failure();
00060 return *(value->top());
00061 }
00062
00063 const T& operator=(const T& c) {
00064 if (has_value()) {
00065 if (c != *(value->top()))
00066 throw failure();
00067 return *(value->top());
00068 }
00069 value->top().reset(new T(c));
00070 return *(value->top());
00071 }
00072
00073 void reset() const {
00074 value->top().release();
00075 value->top().reset(NULL);
00076 }
00077
00078 };
00079
00082 template <typename T>
00083 struct pattern_model<variable<T> > {
00084 struct model {
00085 typedef variable<T> type;
00086 typedef T build_type;
00087 };
00088 };
00089
00090 template <typename T>
00091 struct listable_model<variable<T> > {
00092 struct model {
00093 typedef variable<T> type;
00094 };
00095 };
00096
00097 }
00098
00099 #endif