1 #ifndef __OPERAND_HPP_
2 #define __OPERAND_HPP_
3 
4 /* "Species" - a CoreWars evolver.  Copyright (C) 2003 'Varfar'
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 1, or (at your option) any later
9  * version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 /* to implement a generator:
22  * 1) derive publically from COperand
23  * 1) give it an identifier in the EImpl enumeration
24  * 2) make the constructor set the _type member
25  * 3) make COperand factories understand this new implementation and how to identify it
26  * 4) implement the read_ini/write_ini functionality
27  */
28 
29 #include "ini.hpp"
30 #include "exhaust.hpp"
31 
32 class COperand { // an abstract class, use the factory to get an implementation
33 	public:
34 		enum Field {
35 			A,
36 			B,
37 			FIELD_LAST
38 		};
~COperand()39 		virtual ~COperand() {}
40 		// factory
41 		static COperand *NewDefault(const field_t coresize);
42 		static COperand *read_ini(INIFile &ini,const field_t coresize); // create a new implementation
43 		static COperand *read_override_ini(COperand *gen,INIFile &ini); /* loads an implementation;
44 			if the ini specifies a new implementation: if the type is the same as the parent, it will load a diff;
45 			if the type is different, all values must be specified */
46 		// actual query point
47 		virtual void rnd(insn_t &instruction,const Field field) = 0;
48 		// and saving
49 		virtual void write_ini(std::ostream &os) = 0;
50 		virtual void write_override_ini(std::ostream &os,const COperand *parent) = 0;
51 		// misc
same_type(const COperand * gen1,const COperand * gen2)52 		static bool same_type(const COperand *gen1,const COperand *gen2) { return (gen1->type() == gen2->type()); }
53 	protected:
54 		COperand(const field_t coresize);
55 		field_t _coresize;
56 		enum IMPL { // all implementations must be listed here
57 			DISTRIBUTION,
58 			TABLE,
59 			IMPL_LAST
60 		} _type;
type_key()61 		static const char *type_key() { return TYPE_KEY; }
62 		static const char *impl_desc(const IMPL type);
63 		static IMPL desc_to_impl(const char *desc);
type() const64 		const IMPL type() const { return _type; }
65 		virtual void read_ini_impl(INIFile &ini) = 0;
66 		virtual COperand *read_override_ini_impl(INIFile &ini) = 0;
67 	private:
68 		static const char
69 			*TYPE_KEY,
70 			*IMPL_DESC[IMPL_LAST];
71 };
72 
73 #endif // ifndef __OPERAND_HPP__
74 
75