// license:BSD-3-Clause // copyright-holders:Couriersud /// /// \file state_var.h /// #ifndef NL_CORE_STATE_VAR_H_ #define NL_CORE_STATE_VAR_H_ #include "../nltypes.h" #include "../plib/pfmtlog.h" #include "../plib/pstring.h" namespace netlist { /// \brief A persistent variable template. /// Use the state_var template to define a variable whose value is saved. /// Within a device definition use /// /// ``` /// NETLIB_OBJECT(abc) /// { /// NETLIB_CONSTRUCTOR(abc) /// , m_var(*this, "myvar", 0) /// ... /// state_var m_var; /// } /// ``` /// template struct state_var { public: using value_type = T; template //! Constructor. state_var(O & owner, //!< owner must have a netlist() method. const pstring &name, //!< identifier/name for this state variable const T & value //!< Initial value after construction ); template //! Constructor. state_var(O & owner, //!< owner must have a netlist() method. const pstring &name //!< identifier/name for this state variable ); state_var(state_var &&) noexcept = delete; state_var &operator=(state_var &&) noexcept = delete; //! Destructor. ~state_var() noexcept = default; //! Copy Constructor removed. constexpr state_var(const state_var &rhs) = delete; //! Assignment operator to assign value of a state var. constexpr state_var &operator=(const state_var &rhs) noexcept { if (this != &rhs) m_value = rhs.m_value; return *this; } // OSX doesn't like noexcept //! Assignment operator to assign value of type T. constexpr state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; } //! Assignment move operator to assign value of type T. // constexpr state_var &operator=(T &&rhs) noexcept { std::swap(m_value, // rhs); return *this; } constexpr state_var &operator=(T &&rhs) noexcept { m_value = std::move(rhs); return *this; } //! Return non-const value of state variable. constexpr operator T &() noexcept { return m_value; } //! Return const value of state variable. constexpr operator const T &() const noexcept { return m_value; } //! Return non-const value of state variable. constexpr T &var() noexcept { return m_value; } //! Return const value of state variable. constexpr const T &var() const noexcept { return m_value; } //! Return non-const value of state variable. constexpr T &operator()() noexcept { return m_value; } //! Return const value of state variable. constexpr const T &operator()() const noexcept { return m_value; } //! Access state variable by ->. constexpr T *operator->() noexcept { return &m_value; } //! Access state variable by const ->. constexpr const T *operator->() const noexcept { return &m_value; } //! Access state variable by *. constexpr T *operator*() noexcept { return &m_value; } //! Access state variable by const *. constexpr const T *operator*() const noexcept { return &m_value; } private: T m_value; }; /// \brief A persistent array template. /// Use this state_var template to define an array whose contents are /// saved. Please refer to \ref state_var. /// /// \tparam C container class to use. template struct state_container : public C { public: using value_type = typename C::value_type; //! Constructor. template state_container(O & owner, //!< owner must have a netlist() method. const pstring & name, //!< identifier/name for this state variable const value_type &value //!< Initial value after construction ); //! Constructor. template state_container(O & owner, //!< owner must have a netlist() method. const pstring & name, //!< identifier/name for this state variable std::size_t n, //!< number of elements to allocate const value_type &value //!< Initial value after construction ); //! Copy Constructor. state_container(const state_container &rhs) noexcept = default; //! Destructor. ~state_container() noexcept = default; //! Move Constructor. state_container(state_container &&rhs) noexcept = default; state_container &operator=( const state_container &rhs) noexcept = default; state_container &operator=(state_container &&rhs) noexcept = default; }; // ----------------------------------------------------------------------------- // State variables - predefined and c++11 non-optional // ----------------------------------------------------------------------------- /// \brief predefined state variable type for uint8_t using state_var_u8 = state_var; /// \brief predefined state variable type for int8_t using state_var_s8 = state_var; /// \brief predefined state variable type for uint32_t using state_var_u32 = state_var; /// \brief predefined state variable type for int32_t using state_var_s32 = state_var; /// \brief predefined state variable type for sig_t using state_var_sig = state_var; template template state_var::state_var(O &owner, const pstring &name, const T &value) : m_value(value) { owner.state().save(owner, m_value, owner.name(), name); } template template state_var::state_var(O &owner, const pstring &name) { owner.state().save(owner, m_value, owner.name(), name); } template template state_container::state_container(O &owner, const pstring &name, const state_container::value_type &value) { owner.state().save(owner, static_cast(*this), owner.name(), name); for (std::size_t i = 0; i < this->size(); i++) (*this)[i] = value; } template template state_container::state_container(O &owner, const pstring &name, std::size_t n, const state_container::value_type &value) : C(n, value) { owner.state().save(owner, static_cast(*this), owner.name(), name); } // ----------------------------------------------------------------------------- // Externals // ----------------------------------------------------------------------------- extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; extern template struct state_var; } // namespace netlist namespace plib { template struct format_traits> : format_traits { }; } // namespace plib #endif // NL_CORE_STATE_VAR_H_