| #pragma once | 
 |  | 
 | #include <register/hei_register.hpp> | 
 |  | 
 | namespace libhei | 
 | { | 
 |  | 
 | /** | 
 |  * @brief An abstract class for all operator registers. | 
 |  * | 
 |  * Contains member functions and variables that are required for all child | 
 |  * classes. | 
 |  */ | 
 | class OperatorRegister : public Register | 
 | { | 
 |   public: | 
 |     /** @brief Pure virtual destructor. */ | 
 |     virtual ~OperatorRegister() = 0; | 
 |  | 
 |   protected: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_size Size (in bytes) of this register. | 
 |      */ | 
 |     explicit OperatorRegister(size_t i_size) : Register(), iv_result(i_size * 8) | 
 |     {} | 
 |  | 
 |   protected: // Instance variables | 
 |     /** When getBitString() is called on an operator, the resulting value of the | 
 |      *  operation will be stored in this instance variable. */ | 
 |     BitStringBuffer iv_result; | 
 |  | 
 |   public: | 
 |     /** @brief Overloaded from parent class. */ | 
 |     virtual const BitString* getBitString(const Chip& i_chip) const = 0; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     size_t getSize() const | 
 |     { | 
 |         return (BitString::getMinBytes(iv_result.getBitLen())); | 
 |     } | 
 | }; | 
 |  | 
 | // Pure virtual destructor must be defined. | 
 | inline OperatorRegister::~OperatorRegister() {} | 
 |  | 
 | class NotRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_arg Target register for operation. | 
 |      */ | 
 |     explicit NotRegister(Register& i_arg) : | 
 |         OperatorRegister(i_arg.getSize()), iv_child(&i_arg) | 
 |     {} | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~NotRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     NotRegister(const NotRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     NotRegister& operator=(const NotRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         const auto* bs = iv_child->getBitString(i_chip); | 
 |  | 
 |         (const_cast<NotRegister*>(this))->iv_result = ~(*bs); | 
 |  | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const NotRegister& r) const | 
 |     { | 
 |         return r.iv_child == iv_child; | 
 |     } | 
 |  | 
 |     bool operator<(const NotRegister& r) const | 
 |     { | 
 |         return iv_child < r.iv_child; | 
 |     } | 
 |  | 
 |   private: | 
 |     Register* iv_child; | 
 | }; | 
 |  | 
 | class LeftShiftRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_arg    Target register for operation. | 
 |      * @param i_amount The shift value. | 
 |      */ | 
 |     LeftShiftRegister(Register& i_arg, uint16_t i_amount) : | 
 |         OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount) | 
 |     {} | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~LeftShiftRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     LeftShiftRegister(const LeftShiftRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     LeftShiftRegister& operator=(const LeftShiftRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         const auto* bs = iv_child->getBitString(i_chip); | 
 |  | 
 |         (const_cast<LeftShiftRegister*>(this))->iv_result = (*bs) << iv_amount; | 
 |  | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const LeftShiftRegister& r) const | 
 |     { | 
 |         return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); | 
 |     } | 
 |  | 
 |     bool operator<(const LeftShiftRegister& r) const | 
 |     { | 
 |         if (iv_child == r.iv_child) | 
 |             return iv_amount < r.iv_amount; | 
 |         return iv_child < r.iv_child; | 
 |     } | 
 |  | 
 |   private: | 
 |     Register* iv_child; | 
 |     uint16_t iv_amount; | 
 | }; | 
 |  | 
 | class RightShiftRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_arg    Target register for operation. | 
 |      * @param i_amount The shift value. | 
 |      */ | 
 |     RightShiftRegister(Register& i_arg, uint16_t i_amount) : | 
 |         OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount) | 
 |     {} | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~RightShiftRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     RightShiftRegister(const RightShiftRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     RightShiftRegister& operator=(const RightShiftRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         const auto* bs = iv_child->getBitString(i_chip); | 
 |  | 
 |         (const_cast<RightShiftRegister*>(this))->iv_result = (*bs) >> iv_amount; | 
 |  | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const RightShiftRegister& r) const | 
 |     { | 
 |         return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); | 
 |     } | 
 |  | 
 |     bool operator<(const RightShiftRegister& r) const | 
 |     { | 
 |         if (iv_child == r.iv_child) | 
 |             return iv_amount < r.iv_amount; | 
 |         return iv_child < r.iv_child; | 
 |     } | 
 |  | 
 |   private: | 
 |     Register* iv_child; | 
 |     uint16_t iv_amount; | 
 | }; | 
 |  | 
 | class AndRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_left  Target register for operation. | 
 |      * @param i_right Target register for operation. | 
 |      */ | 
 |     AndRegister(Register& i_left, Register& i_right) : | 
 |         OperatorRegister(std::min(i_left.getSize(), i_right.getSize())), | 
 |         iv_left(&i_left), iv_right(&i_right) | 
 |     {} | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~AndRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     AndRegister(const AndRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     AndRegister& operator=(const AndRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         const auto* l_bs = iv_left->getBitString(i_chip); | 
 |         const auto* r_bs = iv_right->getBitString(i_chip); | 
 |  | 
 |         (const_cast<AndRegister*>(this))->iv_result = (*l_bs) & (*r_bs); | 
 |  | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const AndRegister& r) const | 
 |     { | 
 |         return (r.iv_left == iv_left) && (r.iv_right == iv_right); | 
 |     } | 
 |  | 
 |     bool operator<(const AndRegister& r) const | 
 |     { | 
 |         if (iv_left == r.iv_left) | 
 |             return iv_right < r.iv_right; | 
 |         return iv_left < r.iv_left; | 
 |     } | 
 |  | 
 |   private: | 
 |     Register* iv_left; | 
 |     Register* iv_right; | 
 | }; | 
 |  | 
 | class OrRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_left  Target register for operation. | 
 |      * @param i_right Target register for operation. | 
 |      */ | 
 |     OrRegister(Register& i_left, Register& i_right) : | 
 |         OperatorRegister(std::min(i_left.getSize(), i_right.getSize())), | 
 |         iv_left(&i_left), iv_right(&i_right) | 
 |     {} | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~OrRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     OrRegister(const OrRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     OrRegister& operator=(const OrRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         const auto* l_bs = iv_left->getBitString(i_chip); | 
 |         const auto* r_bs = iv_right->getBitString(i_chip); | 
 |  | 
 |         (const_cast<OrRegister*>(this))->iv_result = (*l_bs) | (*r_bs); | 
 |  | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const OrRegister& r) const | 
 |     { | 
 |         return (r.iv_left == iv_left) && (r.iv_right == iv_right); | 
 |     } | 
 |  | 
 |     bool operator<(const OrRegister& r) const | 
 |     { | 
 |         if (iv_left == r.iv_left) | 
 |             return iv_right < r.iv_right; | 
 |         return iv_left < r.iv_left; | 
 |     } | 
 |  | 
 |   private: | 
 |     Register* iv_left; | 
 |     Register* iv_right; | 
 | }; | 
 |  | 
 | class ConstantRegister : public OperatorRegister | 
 | { | 
 |   public: | 
 |     /** | 
 |      * @brief Constructor from components. | 
 |      * @param i_arg A BitStringBuffer containing the constant value. | 
 |      */ | 
 |     explicit ConstantRegister(const BitStringBuffer& i_arg) : | 
 |         OperatorRegister(BitString::getMinBytes(i_arg.getBitLen())) | 
 |     { | 
 |         iv_result = i_arg; | 
 |     } | 
 |  | 
 |     /** @brief Default destructor. */ | 
 |     ~ConstantRegister() = default; | 
 |  | 
 |     /** @brief Default copy constructor. */ | 
 |     ConstantRegister(const ConstantRegister&) = default; | 
 |  | 
 |     /** @brief Default assignment operator. */ | 
 |     ConstantRegister& operator=(const ConstantRegister& r) = default; | 
 |  | 
 |     /** @brief Overloaded from parent class. */ | 
 |     const BitString* getBitString(const Chip& i_chip) const | 
 |     { | 
 |         return &iv_result; | 
 |     } | 
 |  | 
 |     bool operator==(const ConstantRegister& r) const | 
 |     { | 
 |         return r.iv_result == iv_result; | 
 |     } | 
 | }; | 
 |  | 
 | } // end namespace libhei |