diff options
Diffstat (limited to 'src/lib/netlist/plib/pstate.h')
-rw-r--r-- | src/lib/netlist/plib/pstate.h | 173 |
1 files changed, 129 insertions, 44 deletions
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index ac75ca6b69e..72473590b9b 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -1,14 +1,13 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Couriersud -/* - * pstate.h - * - */ #ifndef PSTATE_H_ #define PSTATE_H_ -#include "palloc.h" +/// +/// \file pstate.h +/// + #include "pstring.h" #include "ptypes.h" @@ -28,16 +27,22 @@ public: struct datatype_t { datatype_t(std::size_t bsize, bool bintegral, bool bfloat) - : size(bsize), is_integral(bintegral), is_float(bfloat), is_custom(false) + : m_size(bsize), m_is_integral(bintegral), m_is_float(bfloat), m_is_custom(false) {} explicit datatype_t(bool bcustom) - : size(0), is_integral(false), is_float(false), is_custom(bcustom) + : m_size(0), m_is_integral(false), m_is_float(false), m_is_custom(bcustom) {} - const std::size_t size; - const bool is_integral; - const bool is_float; - const bool is_custom; + std::size_t size() const noexcept { return m_size; } + bool is_integral() const noexcept { return m_is_integral; } + bool is_float() const noexcept { return m_is_float; } + bool is_custom() const noexcept { return m_is_custom; } + + private: + std::size_t m_size; + bool m_is_integral; + bool m_is_float; + bool m_is_custom; }; template<typename T> @@ -45,10 +50,10 @@ public: { return datatype_t(sizeof(T), plib::is_integral<T>::value || std::is_enum<T>::value, - std::is_floating_point<T>::value); + plib::is_floating_point<T>::value); } - class callback_t + struct callback_t { public: using list_t = std::vector<callback_t *>; @@ -58,85 +63,165 @@ public: virtual void on_post_load(state_manager_t &manager) = 0; protected: callback_t() = default; - ~callback_t() = default; - COPYASSIGNMOVE(callback_t, default) + virtual ~callback_t() = default; + PCOPYASSIGNMOVE(callback_t, default) }; struct entry_t { - using list_t = std::vector<plib::unique_ptr<entry_t>>; + using list_t = std::vector<entry_t>; - entry_t(const pstring &stname, const datatype_t &dt, const void *owner, + entry_t(const pstring &item_name, const datatype_t &dt, const void *owner, const std::size_t count, void *ptr) - : m_name(stname), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { } + : m_name(item_name), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { } - entry_t(const pstring &stname, const void *owner, callback_t *callback) - : m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { } + entry_t(const pstring &item_name, const void *owner, callback_t *callback) + : m_name(item_name), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { } + pstring name() const noexcept { return m_name; } + datatype_t dt() const noexcept { return m_dt; } + const void * owner() const noexcept { return m_owner; } + callback_t * callback() const noexcept { return m_callback; } + std::size_t count() const noexcept { return m_count; } + void * ptr() const noexcept { return m_ptr; } + + private: pstring m_name; - const datatype_t m_dt; + datatype_t m_dt; const void * m_owner; callback_t * m_callback; - const std::size_t m_count; + std::size_t m_count; void * m_ptr; }; state_manager_t() = default; + struct saver_t + { + saver_t(state_manager_t &sm, const void *owner, const pstring &member_name) + : m_sm(sm) + , m_owner(owner) + , m_member_name(member_name) + { } + + template <typename XS> + void save_item(XS &some_state, const pstring &item_name) + { + m_sm.save_item(m_owner, some_state, m_member_name + "." + item_name); + } + + state_manager_t &m_sm; + const void * m_owner; + const pstring m_member_name; + }; + template<typename C> - void save_item(const void *owner, C &state, const pstring &stname) + void save_item(const void *owner, C &state, const pstring &item_name) { - save_state_ptr( owner, stname, dtype<C>(), 1, &state); + save_item_dispatch(owner, state, item_name); } template<typename C, std::size_t N> - void save_item(const void *owner, C (&state)[N], const pstring &stname) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + void save_item(const void *owner, C (&state)[N], const pstring &item_name) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) { - save_state_ptr(owner, stname, dtype<C>(), N, &(state[0])); + save_state_ptr(owner, item_name, dtype<C>(), N, &(state[0])); } template<typename C> - void save_item(const void *owner, C *state, const pstring &stname, const std::size_t count) + void save_item(const void *owner, C *state, const pstring &item_name, const std::size_t count) { - save_state_ptr(owner, stname, dtype<C>(), count, state); + save_state_ptr(owner, item_name, dtype<C>(), count, state); } - template<typename C> - void save_item(const void *owner, std::vector<C> &v, const pstring &stname) + template<typename C, typename A> + void save_item(const void *owner, std::vector<C, A> &v, const pstring &item_name) { - save_state_ptr(owner, stname, dtype<C>(), v.size(), v.data()); + save_state_ptr(owner, item_name, dtype<C>(), v.size(), v.data()); } template<typename C, std::size_t N> - void save_item(const void *owner, std::array<C, N> &a, const pstring &stname) + void save_item(const void *owner, std::array<C, N> &a, const pstring &item_name) + { + save_state_ptr(owner, item_name, dtype<C>(), N, a.data()); + } + + void save_state_ptr(const void *owner, const pstring &item_name, const datatype_t &dt, const std::size_t count, void *ptr) + { + m_save.emplace_back(item_name, dt, owner, count, ptr); + } + + void pre_save() + { + for (auto & s : m_custom) + s.callback()->on_pre_save(*this); + } + + void post_load() { - save_state_ptr(owner, stname, dtype<C>(), N, a.data()); + for (auto & s : m_custom) + s.callback()->on_post_load(*this); } - void pre_save(); - void post_load(); - void remove_save_items(const void *owner); + void remove_save_items(const void *owner) + { + auto i = m_save.end(); + while (i != m_save.begin()) + { + i--; + if (i->owner() == owner) + i = m_save.erase(i); + } + i = m_custom.end(); + while (i > m_custom.begin()) + { + i--; + if (i->owner() == owner) + i = m_custom.erase(i); + } + } - const std::vector<const entry_t *> save_list() const + std::vector<const entry_t *> save_list() const { std::vector<const entry_t *> ret; - for (auto &i : m_save) - ret.push_back(i.get()); + for (const auto &i : m_save) + ret.push_back(&i); return ret; } - void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr); - protected: private: + + template<typename C> + std::enable_if_t<plib::is_integral<C>::value || std::is_enum<C>::value + || plib::is_floating_point<C>::value> + save_item_dispatch(const void *owner, C &state, const pstring &item_name) + { + save_state_ptr( owner, item_name, dtype<C>(), 1, &state); + } + + template<typename C> + std::enable_if_t<!(plib::is_integral<C>::value || std::is_enum<C>::value + || plib::is_floating_point<C>::value)> + save_item_dispatch(const void *owner, C &state, const pstring &item_name) + { + saver_t sav(*this, owner, item_name); + state.save_state(sav); + } + entry_t::list_t m_save; entry_t::list_t m_custom; }; -template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname); +template<> +inline void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &item_name) +{ + m_custom.emplace_back(item_name, owner, &state); + state.register_state(*this, item_name); +} + } // namespace plib -#endif /* PSTATE_H_ */ +#endif // PSTATE_H_ |