CaFactory.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of nucad (Non-Uniform CA Designer).
00005  *
00006  * nucad is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * any later version.
00010  *
00011  * nucad is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with nucad.  If not, see <http://www.gnu.org/licenses/>.
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         // abort compilation if input INPUT is already bound
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         // abort compilation if output OUTPUT is already bound
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

Generated on Sat May 2 16:39:31 2009 for nucad by  doxygen 1.5.4