summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_factory.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_factory.h')
-rw-r--r--src/lib/netlist/nl_factory.h258
1 files changed, 164 insertions, 94 deletions
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 271bf72bf90..ed4eb276c1f 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -1,164 +1,234 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * nl_factory.h
- *
- *
- */
+
+///
+/// \file nl_factory.h
+///
#ifndef NLFACTORY_H_
#define NLFACTORY_H_
#include "nltypes.h"
+
#include "plib/palloc.h"
+#include "plib/pmempool.h"
+#include "plib/psource.h"
#include "plib/ptypes.h"
+#include <tuple>
+#include <utility>
#include <vector>
-#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param) \
+#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
+ NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param)
-#define NETLIB_DEVICE_IMPL(chip, p_name, p_def_param) \
+#define NETLIB_DEVICE_IMPL(chip, p_name, p_def_param) \
NETLIB_DEVICE_IMPL_NS(devices, chip, p_name, p_def_param)
-#define NETLIB_DEVICE_IMPL_NS(ns, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param) \
-
-#define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \
- static plib::unique_ptr<factory::element_t> NETLIB_NAME(p_alias ## _c) \
- (const pstring &classname) \
- { \
- return plib::make_unique<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(p_name, classname, p_def_param, pstring(__FILE__)); \
- } \
- \
- factory::constructor_ptr_t decl_ ## p_alias = NETLIB_NAME(p_alias ## _c);
-
-namespace netlist {
- class device_t;
- class nlparse_t;
- class setup_t;
- class netlist_state_t;
-
-namespace factory {
- // -----------------------------------------------------------------------------
+#define NETLIB_DEVICE_IMPL_NS(ns, chip, p_name, p_def_param) \
+ NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param)
+
+#define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \
+ static factory::element_t::uptr NETLIB_NAME(p_alias##_c)() \
+ { \
+ using devtype = factory::device_element_t<ns ::NETLIB_NAME(chip)>; \
+ factory::properties sl(p_def_param, PSOURCELOC()); \
+ return devtype::create(p_name, std::move(sl)); \
+ } \
+ \
+ extern factory::constructor_ptr_t decl_##p_alias; \
+ factory::constructor_ptr_t decl_##p_alias = NETLIB_NAME(p_alias##_c);
+
+namespace netlist::factory
+{
+ enum class element_type
+ {
+ BUILTIN,
+ MACRO
+ };
+
+ struct properties
+ {
+ properties(const pstring & default_parameter,
+ plib::source_location &&location)
+ : m_default_parameter(default_parameter)
+ , m_location(std::move(location))
+ , m_type(element_type::BUILTIN)
+ {
+ }
+
+ ~properties() = default;
+ PCOPYASSIGNMOVE(properties, default)
+
+ pstring default_parameter() const noexcept
+ {
+ return m_default_parameter;
+ }
+
+ plib::source_location source() const noexcept { return m_location; }
+
+ element_type type() const noexcept { return m_type; }
+
+ properties &set_type(element_type t) noexcept
+ {
+ m_type = t;
+ return *this;
+ }
+
+ private:
+ pstring m_default_parameter;
+ plib::source_location m_location;
+ element_type m_type;
+ };
+
+ // -------------------------------------------------------------------------
// net_dev class factory
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class element_t
{
public:
- element_t(const pstring &name, const pstring &classname,
- const pstring &def_param);
- element_t(const pstring &name, const pstring &classname,
- const pstring &def_param, const pstring &sourcefile);
+ using dev_uptr = device_arena::unique_ptr<core_device_t>;
+ using uptr = host_arena::unique_ptr<element_t>;
+ using pointer = element_t *;
+
+ element_t(const pstring &name, properties &&props);
virtual ~element_t() = default;
- COPYASSIGNMOVE(element_t, default)
+ PCOPYASSIGNMOVE(element_t, default)
+
+ virtual dev_uptr
+ make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name)
+ = 0;
- virtual pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) = 0;
- virtual void macro_actions(nlparse_t &nparser, const pstring &name)
+ pstring name() const noexcept { return m_name; }
+ pstring param_desc() const noexcept
{
- plib::unused_var(nparser);
- plib::unused_var(name);
+ return m_properties.default_parameter();
}
-
- const pstring &name() const { return m_name; }
- const pstring &classname() const { return m_classname; }
- const pstring &param_desc() const { return m_def_param; }
- const pstring &sourcefile() const { return m_sourcefile; }
+ plib::source_location source() const noexcept
+ {
+ return m_properties.source();
+ }
+ element_type type() const noexcept { return m_properties.type(); }
private:
- pstring m_name; /* device name */
- pstring m_classname; /* device class name */
- pstring m_def_param; /* default parameter */
- pstring m_sourcefile; /* source file */
+ pstring m_name; //!< device name
+ properties m_properties; //!< source file and other information and
+ //!< settings
};
- template <class C>
+ template <class C, typename... Args>
class device_element_t : public element_t
{
public:
- device_element_t(const pstring &name, const pstring &classname,
- const pstring &def_param)
- : element_t(name, classname, def_param) { }
- device_element_t(const pstring &name, const pstring &classname,
- const pstring &def_param, const pstring &sourcefile)
- : element_t(name, classname, def_param, sourcefile) { }
-
- pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override
+ using constructor_data_t = typename C::constructor_data_t;
+
+ device_element_t(const pstring &name, properties &&props,
+ Args &&...args)
+ : element_t(name, std::move(props))
+ , m_args(std::forward<Args>(args)...)
+ {
+ }
+
+ template <std::size_t... Is>
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...> &args,
+ std::index_sequence<Is...>)
+ {
+ return plib::make_unique<C>(
+ pool, constructor_data_t{anetlist, name},
+ std::forward<Args>(std::get<Is>(args))...);
+ }
+
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...> &args)
+ {
+ return make_device(pool, anetlist, name, args,
+ std::index_sequence_for<Args...>{});
+ }
+
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name) override
{
- return pool().make_poolptr<C>(anetlist, name);
+ return make_device(pool, anetlist, name, m_args);
}
+
+ static uptr
+ create(const pstring &name, properties &&props, Args &&...args)
+ {
+ return plib::make_unique<device_element_t<C, Args...>, host_arena>(
+ name, std::move(props), std::forward<Args>(args)...);
+ }
+
+ private:
+ std::tuple<Args...> m_args;
};
- class list_t : public std::vector<plib::unique_ptr<element_t>>
+ class list_t : public std::vector<element_t::uptr>
{
public:
explicit list_t(log_type &alog);
~list_t() = default;
- COPYASSIGNMOVE(list_t, delete)
+ PCOPYASSIGNMOVE(list_t, delete)
- template<class device_class>
- void register_device(const pstring &name, const pstring &classname,
- const pstring &def_param)
+ template <class device_class, typename... Args>
+ void add(const pstring &name, properties &&props, Args &&...args)
{
- register_device(plib::make_unique<device_element_t<device_class>>(name, classname, def_param));
+ add(device_element_t<device_class, Args...>::create(
+ name, std::move(props), std::forward<Args>(args)...));
}
- void register_device(plib::unique_ptr<element_t> &&factory);
+ void add(element_t::uptr &&factory) noexcept(false);
- element_t * factory_by_name(const pstring &devname);
+ element_t::pointer
+ factory_by_name(const pstring &devname) noexcept(false);
template <class C>
- bool is_class(element_t *f)
+ bool is_class(element_t::pointer f) noexcept
{
- return dynamic_cast<device_element_t<C> *>(f) != nullptr;
+ return bool(plib::dynamic_downcast<device_element_t<C> *>(f));
}
+ bool exists(const pstring &name) const noexcept;
+
private:
log_type &m_log;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// factory_creator_ptr_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- using constructor_ptr_t = plib::unique_ptr<element_t> (*)(const pstring &classname);
+ using constructor_ptr_t = element_t::uptr (*const)();
template <typename T>
- plib::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
- const pstring &def_param)
+ element_t::uptr constructor_t(const pstring &name, properties &&props)
{
- return plib::make_unique<device_element_t<T>>(name, classname, def_param);
+ return plib::make_unique<device_element_t<T>, host_arena>(
+ name, std::move(props));
}
- // -----------------------------------------------------------------------------
- // factory_lib_entry_t: factory class to wrap macro based chips/elements
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+ // library_element_t: factory class to wrap macro based chips/elements
+ // -------------------------------------------------------------------------
class library_element_t : public element_t
{
public:
+ library_element_t(const pstring &name, properties &&props);
- library_element_t(const pstring &name, const pstring &classname,
- const pstring &def_param, const pstring &source)
- : element_t(name, classname, def_param, source)
- {
- }
-
- pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override;
-
- void macro_actions(nlparse_t &nparser, const pstring &name) override;
-
- private:
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name) override;
};
- } // namespace factory
+} // namespace netlist::factory
- namespace devices {
- void initialize_factory(factory::list_t &factory);
- } // namespace devices
-} // namespace netlist
+namespace netlist::devices
+{
+ void initialize_factory(factory::list_t &factory);
+} // namespace netlist::devices
-#endif /* NLFACTORY_H_ */
+#endif // NLFACTORY_H_