00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #ifndef CA_FACTORY_H
00027 #define CA_FACTORY_H
00028
00029 #include "Ca.h"
00030
00031 #ifndef BUILDING_DOX
00032 # include <string>
00033 #endif
00034
00035 class CaEvaluator;
00036
00041 class CaEvaluatorFactory {
00042 public:
00043 CaEvaluatorFactory();
00044 ~CaEvaluatorFactory();
00045
00051 CaEvaluator *create(const std::string &name);
00052
00059 void printList(std::ostream &str);
00060
00061 private:
00062 struct Private;
00063 Private *d;
00064 };
00065
00067 template <bool> struct CT_ASSERT;
00069 template <> struct CT_ASSERT <true> { };
00070
00075 class BindNothing
00076 #ifndef BUILDING_DOX
00077 : public IGateBinding
00078 #endif
00079 {
00080 public:
00081 static const TBus BOUND_INPUTS = 0;
00082 static const TBus BOUND_OUTPUTS = 0;
00083 public:
00084 virtual IGateBinding* clone() const {
00085 return new BindNothing(*this);
00086 }
00087 virtual void setInput(CaState &, TBus) const {
00088 }
00089 virtual void setOutput(CaState &, TBus) const {
00090 }
00091 virtual TBus getOutput(const CaState &) const {
00092 return 0;
00093 }
00094 };
00095
00104 template <int INPUT, int ROW, int COL, class PARENT = BindNothing>
00105 class BindInput:
00106 #ifdef BUILDING_DOX
00107 public IGateBinding
00108 #else
00109 public PARENT
00110 #endif
00111 {
00112 public:
00113 static const TBus MASK = 1 << INPUT;
00114 static const TBus BOUND_INPUTS = PARENT::BOUND_INPUTS | MASK;
00115 static const TBus BOUND_OUTPUTS = PARENT::BOUND_OUTPUTS;
00116
00117 public:
00118 virtual IGateBinding* clone() const {
00119 return new BindInput(*this);
00120 }
00121 virtual void setInput(CaState &ca, TBus in) const {
00122 PARENT::setInput(ca, in);
00123 ca.setCellAtPos(Pos(ROW, COL), in & MASK);
00124 }
00125
00126 private:
00127
00128 CT_ASSERT<!(PARENT::BOUND_INPUTS & MASK)>
00129 ___COMPILE_TIME_ERROR__INPUT_ALREADY_BOUND___;
00130 };
00131
00140 template <int OUTPUT, int ROW, int COL, class PARENT = BindNothing>
00141 class BindOutput:
00142 #ifdef BUILDING_DOX
00143 public IGateBinding
00144 #else
00145 public PARENT
00146 #endif
00147 {
00148 public:
00149 static const TBus MASK = 1 << OUTPUT;
00150 static const TBus BOUND_INPUTS = PARENT::BOUND_INPUTS;
00151 static const TBus BOUND_OUTPUTS = PARENT::BOUND_OUTPUTS | MASK;
00152
00153 public:
00154 virtual IGateBinding* clone() const {
00155 return new BindOutput(*this);
00156 }
00157 virtual void setOutput(CaState &ca, TBus out) const {
00158 PARENT::setOutput(ca, out);
00159 ca.setCellAtPos(Pos(ROW, COL), out & MASK);
00160 }
00161 virtual TBus getOutput(const CaState &ca) const {
00162 TBus val = ca.getCellAtPos(Pos(ROW,COL));
00163 val <<= OUTPUT;
00164 val |= PARENT::getOutput(ca);
00165 return val;
00166 }
00167
00168 private:
00169
00170 CT_ASSERT<!(PARENT::BOUND_OUTPUTS & MASK)>
00171 ___COMPILE_TIME_ERROR__OUTPUT_ALREADY_BOUND___;
00172 };
00173
00181 template <int N_IN, int N_OUT>
00182 class AbstractGate: public IGate {
00183 public:
00184 virtual size_t nInputs() const {
00185 return N_IN;
00186 }
00187 virtual size_t nOutputs() const {
00188 return N_OUT;
00189 }
00190 };
00191
00196 template <int N>
00197 class BusGate: public AbstractGate<N, N> {
00198 public:
00199 virtual IGate* clone() const {
00200 return new BusGate(*this);
00201 }
00202 virtual TBus operator[] (TBus in) const {
00203 return in;
00204 }
00205 };
00206
00211 template <int N>
00212 class CrossGate: public AbstractGate<N, N> {
00213 public:
00214 virtual IGate* clone() const {
00215 return new CrossGate(*this);
00216 }
00217 virtual TBus operator[] (TBus in) const {
00218 TBus out = 0;
00219 for (int i = 0; i < N; ++i) {
00220 const TBus mask = 1 << (N - 1 -i);
00221 if (in & mask)
00222 out |= 1 << i;
00223 }
00224 return out;
00225 }
00226 };
00227
00234 template <int N>
00235 class MulGate: public AbstractGate<N, N> {
00236 static const int A = N >> 1;
00237 static const int B = N - A;
00238 public:
00239 virtual IGate* clone() const {
00240 return new MulGate(*this);
00241 }
00242 virtual TBus operator[] (TBus in) const {
00243 TBus inA = in & ((1 << A) - 1);
00244 in >>= A;
00245 TBus inB = in & ((1 << B) - 1);
00246 TBus out = inA * inB;
00247 return out & ((1 << N) - 1);
00248 }
00249 };
00250
00256 template <int N>
00257 class CommonGateBase: public AbstractGate<N, 1> {
00258 public:
00259 virtual TBus operator[] (TBus in) const {
00260 bool out = this->init();
00261 for (unsigned i = 0; i < N; ++i)
00262 this->perform (out, in & (1 << i));
00263 return out;
00264 }
00265
00266 protected:
00271 virtual bool init() const = 0;
00272
00278 virtual void perform(bool &out, bool in) const = 0;
00279 };
00280
00285 template <int N>
00286 class AndGate: public CommonGateBase<N> {
00287 public:
00288 virtual IGate* clone() const {
00289 return new AndGate(*this);
00290 }
00291 protected:
00292 virtual bool init() const {
00293 return true;
00294 }
00295 virtual void perform(bool &out, bool in) const {
00296 out &= in;
00297 }
00298 };
00299
00304 template <int N>
00305 class OrGate: public CommonGateBase<N> {
00306 public:
00307 virtual IGate* clone() const {
00308 return new OrGate(*this);
00309 }
00310 protected:
00311 virtual bool init() const {
00312 return false;
00313 }
00314 virtual void perform(bool &out, bool in) const {
00315 out |= in;
00316 }
00317 };
00318
00323 template <int N>
00324 class XorGate: public CommonGateBase<N> {
00325 public:
00326 virtual IGate* clone() const {
00327 return new XorGate(*this);
00328 }
00329 protected:
00330 virtual bool init() const {
00331 return false;
00332 }
00333 virtual void perform(bool &out, bool in) const {
00334 out ^= in;
00335 }
00336 };
00337
00338 #endif // CA_FACTORY_H