// Electrical quantities classes // ----------------------------- #ifndef EPOWER #include "global.hpp" // These classes define the real numeric quantities in electric circuits // and the operations on meaningful combinations of them. // Revised version using local macros to reduce repetitive code. // Interactions among the classes: // ------------------------------ // Forward class definitions to allow any of the related classes to // declare function parameters or return values of any of the others: class ECurrent; class EPower; class EPotential; class EResistance; // Macro to confer mutual accessibility among the four classes: #define MutualFriends \ friend ECurrent; friend EPotential; friend EPower; friend EResistance // Binary operator functions: (all are inline) // 1. Both operands of the same class: They are defined as members of that // class, and are usually defined inline within the class definition. // 2. Two operands of different classes: They are members of the class // of the left operand, but are defined outside the class definition // in order to avoid forward references to undefined classes. // The output stream operators are defined as non-member friends, but coded // inline within the class definition. // Local type codes // ---------------- typedef double EQuanI; // Internal type for member data in all classes typedef double EQuanC; // Conversion type for constructor parameter typedef double EQuanP; // Pure number type for arithmetic operations #define EPOTENTIAL const EPotential #define ECURRENT const ECurrent #define ERESISTANCE const EResistance #define EPOWER const EPower #define EQUANI const EQuanI #define EQUANC const EQuanC #define EQUANP const EQuanP #define PureType EQuanP // The following generative macros localize common code patterns // among the classes: #define ClassStart(Class) class Class { \ MutualFriends; \ EQuanI value; \ public: \ static const char unitName[10]; \ Class (EQUANC x = 0) : value(x) {} #define Relational(Class, op) \ bool operator op (const Class rs) const {return value op rs.value;} #define Relationals(Class) \ Relational(Class, ==) Relational(Class, <) Relational(Class, <=) \ Relational(Class, !=) Relational(Class, >) Relational(Class, >=) #define OutputStream(Class) \ friend ostream& operator<< (ostream& ls, const Class rs) \ {return ls << rs.value << ' ' << Class::unitName;}; // Voltage (potential difference) class // ------------------------------------ ClassStart(EPotential) #define Class EPotential #include "Additive.hpp" EPower operator* (ECURRENT i) const; EResistance operator/ (ECURRENT i) const; ECurrent operator/ (ERESISTANCE r) const; Relationals(EPotential) OutputStream(EPotential) #undef Class }; // Resistance class // ---------------- ClassStart(EResistance) EResistance operator& (ERESISTANCE rs) const // Series connection {return value + rs.value;} EResistance operator| (ERESISTANCE rs) const // Parallel connection {return value * rs.value / (value + rs.value);} EPotential operator* (ECURRENT rs) const; // Ohm's law Relationals(EResistance) OutputStream(EResistance) }; // Current class // ------------- ClassStart(ECurrent) #define Class ECurrent #include "Additive.hpp" EPower operator* (EPOTENTIAL v) const ; EPotential operator* (ERESISTANCE r) const ; Relationals(ECurrent) OutputStream(ECurrent) #undef Class }; // Power class // ----------- ClassStart(EPower) #define Class EPower #include "Additive.hpp" EPotential operator/(ECURRENT i) const ; ECurrent operator/(EPOTENTIAL v) const ; Relationals(EPower) OutputStream(EPower) #undef Class }; // Arithmetic involving mixed classes // ---------------------------------- inline EPower EPotential ::operator* (ECURRENT rs) const {return value * rs.value;} inline EPower ECurrent ::operator* (EPOTENTIAL rs) const {return value * rs.value;} inline EPotential EPower ::operator/ (ECURRENT rs) const {return value / rs.value;} inline ECurrent EPower ::operator/ (EPOTENTIAL rs) const {return value / rs.value;} inline EPotential EResistance::operator* (ECURRENT rs) const {return value * rs.value;} inline EPotential ECurrent ::operator* (ERESISTANCE rs) const {return value * rs.value;} inline ECurrent EPotential ::operator/ (ERESISTANCE rs) const {return value / rs.value;} inline EResistance EPotential ::operator/ (ECURRENT rs) const {return value / rs.value;} #undef MutualFriends #undef ClassStart #undef Relationals #undef OutputStream #endif