mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
Merge branch 'master' of https://github.com/mamedev/mame
This commit is contained in:
commit
284f196df1
@ -53,6 +53,7 @@ project "netlist"
|
||||
MAME_DIR .. "src/lib/netlist/plib/pconfig.h",
|
||||
MAME_DIR .. "src/lib/netlist/plib/palloc.h",
|
||||
MAME_DIR .. "src/lib/netlist/plib/pchrono.h",
|
||||
MAME_DIR .. "src/lib/netlist/plib/pgsl.h",
|
||||
MAME_DIR .. "src/lib/netlist/plib/penum.h",
|
||||
MAME_DIR .. "src/lib/netlist/plib/pexception.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/plib/pexception.h",
|
||||
|
@ -127,7 +127,7 @@ protected:
|
||||
netlist::host_arena::unique_ptr<plib::dynlib_base> static_solver_lib() const noexcept override
|
||||
{
|
||||
//return plib::make_unique<plib::dynlib_static>(nullptr);
|
||||
return netlist::host_arena::make_unique<plib::dynlib_static>(nl_static_solver_syms);
|
||||
return plib::make_unique<plib::dynlib_static, netlist::host_arena>(nl_static_solver_syms);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -169,7 +169,7 @@ protected:
|
||||
|
||||
netlist::host_arena::unique_ptr<plib::dynlib_base> static_solver_lib() const noexcept override
|
||||
{
|
||||
return netlist::host_arena::make_unique<plib::dynlib_static>(nullptr);
|
||||
return plib::make_unique<plib::dynlib_static, netlist::host_arena>(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -181,7 +181,7 @@ class netlist_mame_device::netlist_mame_t : public netlist::netlist_state_t
|
||||
public:
|
||||
|
||||
netlist_mame_t(netlist_mame_device &parent, const pstring &name)
|
||||
: netlist::netlist_state_t(name, netlist::host_arena::make_unique<netlist_mame_device::netlist_mame_callbacks_t>(parent))
|
||||
: netlist::netlist_state_t(name, plib::make_unique<netlist_mame_device::netlist_mame_callbacks_t, netlist::host_arena>(parent))
|
||||
, m_parent(parent)
|
||||
{
|
||||
}
|
||||
@ -978,7 +978,8 @@ netlist::host_arena::unique_ptr<netlist::netlist_state_t> netlist_mame_device::b
|
||||
{
|
||||
try
|
||||
{
|
||||
auto lnetlist = netlist::host_arena::make_unique<netlist::netlist_state_t>("netlist", netlist::host_arena::make_unique<netlist_validate_callbacks_t>());
|
||||
auto lnetlist = plib::make_unique<netlist::netlist_state_t, netlist::host_arena>("netlist",
|
||||
plib::make_unique<netlist_validate_callbacks_t, netlist::host_arena>());
|
||||
// enable validation mode
|
||||
lnetlist->set_extended_validation(true);
|
||||
common_dev_start(lnetlist.get());
|
||||
|
@ -415,8 +415,8 @@ namespace analog
|
||||
else
|
||||
{
|
||||
// linear
|
||||
const auto Sqr1(static_cast<nl_fptype>(plib::pow(Vdsat - Vds, 2)));
|
||||
const auto Sqr2(static_cast<nl_fptype>(plib::pow(nlconst::two() * Vdsat - Vds, 2)));
|
||||
const auto Sqr1(plib::narrow_cast<nl_fptype>(plib::pow(Vdsat - Vds, 2)));
|
||||
const auto Sqr2(plib::narrow_cast<nl_fptype>(plib::pow(nlconst::two() * Vdsat - Vds, 2)));
|
||||
Cgb = 0;
|
||||
Cgs = m_CoxWL * (nlconst::one() - Sqr1 / Sqr2) * nlconst::two_thirds();
|
||||
Cgd = m_CoxWL * (nlconst::one() - Vdsat * Vdsat / Sqr2) * nlconst::two_thirds();
|
||||
|
@ -115,7 +115,7 @@ namespace netlist
|
||||
, m_VL(*this, "VL")
|
||||
, m_VREF(*this, "VREF")
|
||||
{
|
||||
m_type = static_cast<int>(m_modacc.m_TYPE);
|
||||
m_type = plib::narrow_cast<int>(m_modacc.m_TYPE);
|
||||
if (m_type < 1 || m_type > 3)
|
||||
{
|
||||
log().fatal(MF_OPAMP_UNKNOWN_TYPE(m_type));
|
||||
|
@ -561,11 +561,11 @@ namespace analog
|
||||
{
|
||||
register_subalias("P", P());
|
||||
register_subalias("N", N());
|
||||
if (m_func() != "")
|
||||
if (!m_func().empty())
|
||||
m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_IS_TIMESTEP(!m_func().empty())
|
||||
|
||||
NETLIB_TIMESTEPI()
|
||||
{
|
||||
@ -609,11 +609,11 @@ namespace analog
|
||||
{
|
||||
register_subalias("P", P());
|
||||
register_subalias("N", N());
|
||||
if (m_func() != "")
|
||||
if (!m_func().empty())
|
||||
m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_IS_TIMESTEP(!m_func().empty())
|
||||
NETLIB_TIMESTEPI()
|
||||
{
|
||||
m_t += step;
|
||||
|
@ -25,11 +25,13 @@ VSBUILD = $(SRC)/buildVS
|
||||
DOC = $(SRC)/documentation
|
||||
|
||||
TIDY_FLAGSX = -checks=*,-google*,-hicpp*,readability*,-fuchsia*,cert-*,-android-*,
|
||||
TIDY_FLAGSX += -llvm-header-guard,-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
TIDY_FLAGSX += -llvm-header-guard,
|
||||
# TIDY_FLAGSX += -cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
#TIDY_FLAGSX += -cppcoreguidelines-owning-memory,
|
||||
TIDY_FLAGSX += -modernize-use-default-member-init,-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
TIDY_FLAGSX += -modernize-pass-by-value,-cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
TIDY_FLAGSX += -modernize-pass-by-value,
|
||||
#TIDY_FLAGSX += -cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
TIDY_FLAGSX += -cppcoreguidelines-avoid-magic-numbers,
|
||||
TIDY_FLAGSX += -cppcoreguidelines-macro-usage,
|
||||
TIDY_FLAGSX += -cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,
|
||||
@ -37,7 +39,7 @@ TIDY_FLAGSX += -bugprone-macro-parentheses,
|
||||
#TIDY_FLAGSX += -misc-macro-parentheses,
|
||||
TIDY_FLAGSX += -bugprone-too-small-loop-variable,
|
||||
TIDY_FLAGSX += -modernize-use-trailing-return-type,
|
||||
TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
#TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
TIDY_FLAGSX += -readability-magic-numbers,-readability-braces-around-statements,
|
||||
TIDY_FLAGSX += -readability-implicit-bool-conversion,
|
||||
TIDY_FLAGSX += -readability-named-parameter,-readability-function-size,
|
||||
@ -85,7 +87,7 @@ CC = g++
|
||||
LD = @g++
|
||||
MD = @mkdir
|
||||
RM = @rm
|
||||
CLANG_TIDY = clang-tidy-10
|
||||
CLANG_TIDY = clang-tidy-11
|
||||
DEPENDCC=$(CC)
|
||||
|
||||
|
||||
@ -132,6 +134,8 @@ POBJS := \
|
||||
PMAIN := $(POBJ)/pmain.o
|
||||
|
||||
NLOBJS := \
|
||||
$(NLOBJ)/solver/nld_solver.o \
|
||||
$(NLOBJ)/solver/nld_matrix_solver.o \
|
||||
$(NLOBJ)/nl_base.o \
|
||||
$(NLOBJ)/nl_parser.o \
|
||||
$(NLOBJ)/nl_setup.o \
|
||||
@ -142,8 +146,6 @@ NLOBJS := \
|
||||
$(NLOBJ)/analog/nld_switches.o \
|
||||
$(NLOBJ)/analog/nlid_twoterm.o \
|
||||
$(NLOBJ)/analog/nld_opamps.o \
|
||||
$(NLOBJ)/solver/nld_solver.o \
|
||||
$(NLOBJ)/solver/nld_matrix_solver.o \
|
||||
$(NLOBJ)/tools/nl_convert.o \
|
||||
$(NLOBJ)/generated/static_solvers.o \
|
||||
$(NLOBJ)/devices/nld_2102A.o \
|
||||
@ -287,27 +289,32 @@ native:
|
||||
$(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra "
|
||||
|
||||
gcc9:
|
||||
$(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -fext-numeric-literals -Wall -pedantic -Wpedantic -Wsign-compare -Wextra" EXTRALIBS="-lquadmath"
|
||||
$(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -Wall -pedantic -Wpedantic -fext-numeric-literals -Wsign-compare -Wextra" EXTRALIBS="-lquadmath"
|
||||
|
||||
clang:
|
||||
#$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
|
||||
$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native \
|
||||
-mllvm -inline-threshold=2000 \
|
||||
-Wunknown-warning-option \
|
||||
-Weverything -Wall -pedantic -Wpedantic -Wunused-private-field \
|
||||
-Werror -Wno-padded -Wno-weak-vtables -Wno-weak-template-vtables -Wno-unused-template \
|
||||
-Wno-missing-variable-declarations -Wno-float-equal -Wconversion \
|
||||
-Wmissing-variable-declarations -Wno-float-equal -Wconversion \
|
||||
-Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral \
|
||||
-Wno-exit-time-destructors -Winconsistent-missing-destructor-override"
|
||||
-Wno-exit-time-destructors -Winconsistent-missing-destructor-override \
|
||||
-Wno-return-std-move-in-c++11 -Wno-unreachable-code"
|
||||
|
||||
clang-libc:
|
||||
#clang-11 currently broken
|
||||
#$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
|
||||
$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang-libc CEXTRAFLAGS="-march=native \
|
||||
$(MAKE) CC=clang++-10 LD=clang++-10 OBJ=obj/clang-libc CEXTRAFLAGS="-march=native \
|
||||
-stdlib=libc++ -mllvm -inline-threshold=2000 \
|
||||
-Wunknown-warning-option \
|
||||
-Weverything -Wall -pedantic -Wpedantic -Wunused-private-field \
|
||||
-Werror -Wno-padded -Wno-weak-vtables -Wno-weak-template-vtables -Wno-unused-template \
|
||||
-Wno-missing-variable-declarations -Wno-float-equal -Wconversion \
|
||||
-Wmissing-variable-declarations -Wno-float-equal -Wconversion \
|
||||
-Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral \
|
||||
-Wno-exit-time-destructors -Winconsistent-missing-destructor-override" \
|
||||
-Wno-exit-time-destructors -Winconsistent-missing-destructor-override \
|
||||
-Wno-return-std-move-in-c++11 -Wno-unreachable-code"
|
||||
LDEXTRAFLAGS=-stdlib=libc++
|
||||
|
||||
clang-5:
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "nl_errstr.h"
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
@ -18,6 +20,8 @@ namespace netlist
|
||||
// nld_base_proxy
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static const std::array<std::pair<const char *, const char *>, 3> power_syms = {{ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}}};
|
||||
|
||||
nld_base_proxy::nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
|
||||
const logic_t *inout_proxied)
|
||||
: device_t(anetlist, name, inout_proxied->logic_family())
|
||||
@ -29,16 +33,15 @@ namespace netlist
|
||||
throw nl_exception(MF_NULLPTR_FAMILY_NP("nld_base_proxy"));
|
||||
}
|
||||
|
||||
const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
|
||||
|
||||
bool f = false;
|
||||
for (const auto & pwr_sym : power_syms)
|
||||
{
|
||||
pstring devname = inout_proxied->device().name();
|
||||
|
||||
auto *tp_ct(anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
auto *tp_ct(anetlist.setup().find_terminal(devname + "." + pstring(pwr_sym.first),
|
||||
/*detail::terminal_type::INPUT,*/ false));
|
||||
auto *tp_cn(anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
auto *tp_cn(anetlist.setup().find_terminal(devname + "." + pstring(pwr_sym.second),
|
||||
/*detail::terminal_type::INPUT,*/ false));
|
||||
if ((tp_ct != nullptr) && (tp_cn != nullptr))
|
||||
{
|
||||
@ -47,8 +50,8 @@ namespace netlist
|
||||
if (!tp_cn->is_analog())
|
||||
throw nl_exception(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name()));
|
||||
|
||||
auto *tp_t = static_cast<analog_t* >(tp_ct);
|
||||
auto *tn_t = static_cast<analog_t *>(tp_cn);
|
||||
auto *tp_t = dynamic_cast<analog_t* >(tp_ct);
|
||||
auto *tn_t = dynamic_cast<analog_t *>(tp_cn);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(),
|
||||
m_tp->name(), m_tn->name(),
|
||||
|
@ -93,7 +93,7 @@ namespace devices
|
||||
, m_compiled(*this, "m_compiled")
|
||||
, m_funcparam({nlconst::zero()})
|
||||
{
|
||||
if (m_func() != "")
|
||||
if (!m_func().empty())
|
||||
m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
|
||||
connect(m_feedback, m_Q);
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ namespace devices
|
||||
|
||||
if (!m_ttbl)
|
||||
{
|
||||
m_ttbl = pool.make_unique<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t>();
|
||||
m_ttbl = plib::make_unique<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t>(pool);
|
||||
truthtable_parser desc_s(m_NO, m_NI,
|
||||
packed_int(m_ttbl->m_out_state.data(), sizeof(m_ttbl->m_out_state[0]) * 8),
|
||||
m_ttbl->m_timing_index.data(), m_ttbl->m_timing_nt.data());
|
||||
@ -448,7 +448,7 @@ namespace devices
|
||||
desc_s.parse(m_desc);
|
||||
}
|
||||
|
||||
return pool.make_unique<tt_type>(anetlist, name, m_family_name, *m_ttbl, m_desc);
|
||||
return plib::make_unique<tt_type>(pool, anetlist, name, m_family_name, *m_ttbl, m_desc);
|
||||
}
|
||||
private:
|
||||
device_arena::unique_ptr<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t> m_ttbl;
|
||||
@ -578,7 +578,7 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
|
||||
for (int j=0; j < 16; j++)
|
||||
m_timing_nt[j] = netlist_time::zero();
|
||||
|
||||
while (!(ttline == ""))
|
||||
while (!ttline.empty())
|
||||
{
|
||||
std::vector<pstring> io(plib::psplit(ttline,"|"));
|
||||
// checks
|
||||
@ -670,7 +670,7 @@ namespace factory
|
||||
#define ENTRYY(n, m, s) case (n * 100 + m): \
|
||||
{ using xtype = devices::netlist_factory_truthtable_t<n, m>; \
|
||||
auto cs=s; \
|
||||
ret = host_arena::make_unique<xtype>(desc.name, std::move(cs)); } \
|
||||
ret = plib::make_unique<xtype, host_arena>(desc.name, std::move(cs)); } \
|
||||
break
|
||||
|
||||
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
|
||||
@ -700,7 +700,7 @@ namespace factory
|
||||
nl_assert_always(false, msg.c_str());
|
||||
}
|
||||
ret->m_desc = desc.desc;
|
||||
ret->m_family_name = (desc.family != "" ? desc.family : pstring(config::DEFAULT_LOGIC_FAMILY()));
|
||||
ret->m_family_name = (!desc.family.empty() ? desc.family : pstring(config::DEFAULT_LOGIC_FAMILY()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@ namespace netlist
|
||||
|
||||
host_arena::unique_ptr<plib::dynlib_base> callbacks_t:: static_solver_lib() const
|
||||
{
|
||||
return host_arena::make_unique<plib::dynlib_static>(nullptr);
|
||||
return plib::make_unique<plib::dynlib_static, host_arena>(nullptr);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -129,9 +129,9 @@ namespace netlist
|
||||
|
||||
m_lib = m_callbacks->static_solver_lib();
|
||||
|
||||
m_setup = host_arena::make_unique<setup_t>(*this);
|
||||
m_setup = plib::make_unique<setup_t, host_arena>(*this);
|
||||
// create the run interface
|
||||
m_netlist = m_pool.make_unique<netlist_t>(*this, name);
|
||||
m_netlist = plib::make_unique<netlist_t>(m_pool, *this, name);
|
||||
|
||||
// Make sure save states are invalidated when a new version is deployed
|
||||
|
||||
@ -313,7 +313,7 @@ namespace netlist
|
||||
case 0:
|
||||
{
|
||||
std::vector<core_device_t *> d;
|
||||
std::vector<nldelegate *> t;
|
||||
std::vector<const nldelegate *> t;
|
||||
log().verbose("Using default startup strategy");
|
||||
for (auto &n : m_nets)
|
||||
for (auto & term : n->core_terms())
|
||||
@ -402,7 +402,7 @@ namespace netlist
|
||||
}
|
||||
|
||||
log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
|
||||
total_time, total_time / static_cast<decltype(total_time)>((total_count > 0) ? total_count : 1));
|
||||
total_time, total_time / gsl::narrow<decltype(total_time)>((total_count > 0) ? total_count : 1));
|
||||
|
||||
log().verbose("Total loop {1:15}", si.m_stat_mainloop());
|
||||
log().verbose("Total time {1:15}", total_time);
|
||||
@ -424,8 +424,8 @@ namespace netlist
|
||||
}
|
||||
|
||||
plib::pperftime_t<true>::type total_overhead = overhead()
|
||||
* static_cast<plib::pperftime_t<true>::type>(total_count)
|
||||
/ static_cast<plib::pperftime_t<true>::type>(200000);
|
||||
* gsl::narrow<plib::pperftime_t<true>::type>(total_count)
|
||||
/ gsl::narrow<plib::pperftime_t<true>::type>(200000);
|
||||
|
||||
log().verbose("Queue Pushes {1:15}", si.m_queue.m_prof_call());
|
||||
log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sortmove());
|
||||
@ -436,7 +436,7 @@ namespace netlist
|
||||
log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
|
||||
log().verbose("Total overhead {1:15}", total_overhead);
|
||||
plib::pperftime_t<true>::type overhead_per_pop = (si.m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
|
||||
/ static_cast<plib::pperftime_t<true>::type>(si.m_queue.m_prof_call());
|
||||
/ gsl::narrow<plib::pperftime_t<true>::type>(si.m_queue.m_prof_call());
|
||||
log().verbose("Overhead per pop {1:11}", overhead_per_pop );
|
||||
log().verbose("");
|
||||
}
|
||||
@ -450,7 +450,7 @@ namespace netlist
|
||||
if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count()
|
||||
&& stats->m_stat_inc_active() > trigger)
|
||||
log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
|
||||
static_cast<nl_fptype>(stats->m_stat_inc_active()) / static_cast<nl_fptype>(stats->m_stat_total_time.count()),
|
||||
gsl::narrow<nl_fptype>(stats->m_stat_inc_active()) / gsl::narrow<nl_fptype>(stats->m_stat_total_time.count()),
|
||||
stats->m_stat_inc_active(), stats->m_stat_total_time.count());
|
||||
}
|
||||
log().verbose("");
|
||||
@ -831,10 +831,8 @@ namespace netlist
|
||||
device.state().setup().register_param_t(*this);
|
||||
}
|
||||
|
||||
param_t::~param_t() noexcept
|
||||
{
|
||||
// placed here to avoid weak vtable warnings
|
||||
}
|
||||
// placed here to avoid weak vtable warnings
|
||||
param_t::~param_t() noexcept = default;
|
||||
|
||||
param_t::param_type_t param_t::param_type() const noexcept(false)
|
||||
{
|
||||
@ -858,14 +856,14 @@ namespace netlist
|
||||
pstring param_t::get_initial(const core_device_t *dev, bool *found) const
|
||||
{
|
||||
pstring res = dev->state().setup().get_initial_param_val(this->name(), "");
|
||||
*found = (res != "");
|
||||
*found = (!res.empty());
|
||||
return res;
|
||||
}
|
||||
|
||||
param_str_t::param_str_t(core_device_t &device, const pstring &name, const pstring &val)
|
||||
: param_t(device, name)
|
||||
{
|
||||
m_param = host_arena::make_unique<pstring>(val);
|
||||
m_param = plib::make_unique<pstring, host_arena>(val);
|
||||
*m_param = device.state().setup().get_initial_param_val(this->name(),val);
|
||||
}
|
||||
|
||||
@ -873,7 +871,7 @@ namespace netlist
|
||||
: param_t(name)
|
||||
{
|
||||
// deviceless parameter, no registration, owner is responsible
|
||||
m_param = host_arena::make_unique<pstring>(val);
|
||||
m_param = plib::make_unique<pstring, host_arena>(val);
|
||||
*m_param = state.setup().get_initial_param_val(this->name(),val);
|
||||
}
|
||||
|
||||
|
@ -708,9 +708,8 @@ namespace netlist
|
||||
#endif
|
||||
|
||||
void set_delegate(const nldelegate &delegate) noexcept { m_delegate = delegate; }
|
||||
nldelegate &delegate() noexcept { return m_delegate; }
|
||||
const nldelegate &delegate() const noexcept { return m_delegate; }
|
||||
inline void run_delegate() noexcept { m_delegate(); }
|
||||
inline void run_delegate() noexcept { return m_delegate(); }
|
||||
private:
|
||||
nldelegate m_delegate;
|
||||
net_t * m_net;
|
||||
@ -997,7 +996,7 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
|
||||
using list_t = std::vector<analog_net_t *>;
|
||||
using list_t = plib::aligned_vector<analog_net_t *>;
|
||||
|
||||
analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
|
||||
|
||||
@ -1209,7 +1208,7 @@ namespace netlist
|
||||
|
||||
pstring valstr() const override
|
||||
{
|
||||
return plib::pfmt("{}").e(static_cast<nl_fptype>(m_param));
|
||||
return plib::pfmt("{}").e(gsl::narrow<nl_fptype>(m_param));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1309,7 +1308,7 @@ namespace netlist
|
||||
public:
|
||||
template <typename P, typename Y=T, typename DUMMY = std::enable_if_t<plib::is_arithmetic<Y>::value>>
|
||||
value_base_t(P ¶m, const pstring &name)
|
||||
: m_value(static_cast<T>(param.value(name)))
|
||||
: m_value(gsl::narrow<T>(param.value(name)))
|
||||
{
|
||||
}
|
||||
template <typename P, typename Y=T, std::enable_if_t<!plib::is_arithmetic<Y>::value, int> = 0>
|
||||
@ -1513,7 +1512,8 @@ namespace netlist
|
||||
|
||||
~device_t() noexcept override = default;
|
||||
|
||||
nldelegate default_delegate() { return nldelegate(&device_t::update, this); }
|
||||
//nldelegate default_delegate() { return nldelegate(&device_t::update, this); }
|
||||
nldelegate default_delegate() { return { &device_t::update, this }; }
|
||||
protected:
|
||||
|
||||
NETLIB_UPDATEI() { }
|
||||
@ -1757,7 +1757,7 @@ namespace netlist
|
||||
template<typename T, typename... Args>
|
||||
device_arena::unique_ptr<T> make_pool_object(Args&&... args)
|
||||
{
|
||||
return m_pool.make_unique<T>(std::forward<Args>(args)...);
|
||||
return plib::make_unique<T>(m_pool, std::forward<Args>(args)...);
|
||||
}
|
||||
// memory pool - still needed in some places
|
||||
device_arena &pool() noexcept { return m_pool; }
|
||||
@ -2302,6 +2302,7 @@ namespace netlist
|
||||
|
||||
inline void detail::net_t::remove_from_active_list(core_terminal_t &term) noexcept
|
||||
{
|
||||
gsl_Expects(!m_list_active.empty());
|
||||
m_list_active.remove(&term);
|
||||
if (m_list_active.empty())
|
||||
railterminal().device().do_dec_active();
|
||||
@ -2309,24 +2310,24 @@ namespace netlist
|
||||
|
||||
inline const analog_net_t & analog_t::net() const noexcept
|
||||
{
|
||||
return static_cast<const analog_net_t &>(core_terminal_t::net());
|
||||
return plib::downcast<const analog_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline analog_net_t & analog_t::net() noexcept
|
||||
{
|
||||
return static_cast<analog_net_t &>(core_terminal_t::net());
|
||||
return plib::downcast<analog_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline nl_fptype terminal_t::operator ()() const noexcept { return net().Q_Analog(); }
|
||||
|
||||
inline logic_net_t & logic_t::net() noexcept
|
||||
{
|
||||
return static_cast<logic_net_t &>(core_terminal_t::net());
|
||||
return plib::downcast<logic_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline const logic_net_t & logic_t::net() const noexcept
|
||||
{
|
||||
return static_cast<const logic_net_t &>(core_terminal_t::net());
|
||||
return plib::downcast<const logic_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline netlist_sig_t logic_input_t::operator()() const noexcept
|
||||
@ -2516,7 +2517,7 @@ namespace netlist
|
||||
if (plib::is_integral<T>::value)
|
||||
if (plib::abs(valx - plib::trunc(valx)) > nlconst::magic(1e-6))
|
||||
throw nl_exception(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p));
|
||||
m_param = static_cast<T>(valx);
|
||||
m_param = plib::narrow_cast<T>(valx);
|
||||
}
|
||||
|
||||
device.state().save(*this, m_param, this->name(), "m_param");
|
||||
@ -2599,7 +2600,7 @@ namespace netlist
|
||||
state_container<C>::state_container(O &owner, const pstring &name,
|
||||
const state_container<C>::value_type & value)
|
||||
{
|
||||
owner.state().save(owner, *static_cast<C *>(this), owner.name(), name);
|
||||
owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
|
||||
for (std::size_t i=0; i < this->size(); i++)
|
||||
(*this)[i] = value;
|
||||
}
|
||||
@ -2610,7 +2611,7 @@ namespace netlist
|
||||
std::size_t n, const state_container<C>::value_type & value)
|
||||
: C(n, value)
|
||||
{
|
||||
owner.state().save(owner, *static_cast<C *>(this), owner.name(), name);
|
||||
owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
|
||||
}
|
||||
|
||||
extern template struct state_var<std::uint8_t>;
|
||||
|
@ -200,6 +200,12 @@ namespace netlist
|
||||
///
|
||||
using MAX_QUEUE_SIZE = std::integral_constant<std::size_t, 512>; // NOLINT
|
||||
|
||||
using use_float_matrix = std::integral_constant<bool, NL_USE_FLOAT_MATRIX>;
|
||||
using use_long_double_matrix = std::integral_constant<bool, NL_USE_LONG_DOUBLE_MATRIX>;
|
||||
using use_float128_matrix = std::integral_constant<bool, NL_USE_FLOAT128>;
|
||||
|
||||
using use_mempool = std::integral_constant<bool, NL_USE_MEMPOOL>;
|
||||
|
||||
/// \brief Floating point types used
|
||||
///
|
||||
/// nl_fptype is the floating point type used throughout the
|
||||
|
@ -76,7 +76,7 @@ namespace factory {
|
||||
|
||||
device_arena::unique_ptr<core_device_t> library_element_t::make_device(device_arena &pool, netlist_state_t &anetlist, const pstring &name)
|
||||
{
|
||||
return pool.make_unique<NETLIB_NAME(wrapper)>(anetlist, name);
|
||||
return plib::make_unique<NETLIB_NAME(wrapper)>(pool, anetlist, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,7 +129,7 @@ namespace factory {
|
||||
netlist_state_t &anetlist,
|
||||
const pstring &name, std::tuple<Args...>& args, std::index_sequence<Is...>)
|
||||
{
|
||||
return pool.make_unique<C>(anetlist, name, std::forward<Args>(std::get<Is>(args))...);
|
||||
return plib::make_unique<C>(pool, anetlist, name, std::forward<Args>(std::get<Is>(args))...);
|
||||
}
|
||||
|
||||
dev_uptr make_device(device_arena &pool,
|
||||
@ -149,7 +149,7 @@ namespace factory {
|
||||
|
||||
static uptr create(const pstring &name, properties &&props, Args&&... args)
|
||||
{
|
||||
return host_arena::make_unique<device_element_t<C, Args...>>(name,
|
||||
return plib::make_unique<device_element_t<C, Args...>, host_arena>(name,
|
||||
std::move(props), std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
@ -194,7 +194,7 @@ namespace factory {
|
||||
template <typename T>
|
||||
element_t::uptr constructor_t(const pstring &name, properties &&props)
|
||||
{
|
||||
return host_arena::make_unique<device_element_t<T>>(name, std::move(props));
|
||||
return plib::make_unique<device_element_t<T>, host_arena>(name, std::move(props));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -83,7 +83,7 @@ bool parser_t::parse(const pstring &nlname)
|
||||
require_token(m_tok_paren_left);
|
||||
token_t name = get_token();
|
||||
require_token(m_tok_paren_right);
|
||||
if (name.str() == nlname || nlname == "")
|
||||
if (name.str() == nlname || nlname.empty())
|
||||
{
|
||||
parse_netlist(name.str());
|
||||
return true;
|
||||
@ -164,8 +164,8 @@ void parser_t::net_truthtable_start(const pstring &nlname)
|
||||
|
||||
netlist::tt_desc desc;
|
||||
desc.name = name;
|
||||
desc.ni = static_cast<unsigned long>(ni);
|
||||
desc.no = static_cast<unsigned long>(no);
|
||||
desc.ni = gsl::narrow<unsigned long>(ni);
|
||||
desc.no = gsl::narrow<unsigned long>(no);
|
||||
desc.family = "";
|
||||
|
||||
while (true)
|
||||
|
@ -200,7 +200,7 @@ namespace netlist
|
||||
|| plib::abs(value) > nlconst::magic(1e9))
|
||||
register_param(param, plib::pfmt("{1:.9}").e(value));
|
||||
else
|
||||
register_param(param, plib::pfmt("{1}")(static_cast<long>(value)));
|
||||
register_param(param, plib::pfmt("{1}")(gsl::narrow<long>(value)));
|
||||
}
|
||||
|
||||
void nlparse_t::register_param(const pstring ¶m, const pstring &value)
|
||||
@ -248,7 +248,7 @@ namespace netlist
|
||||
|
||||
void nlparse_t::register_lib_entry(const pstring &name, factory::properties &&props)
|
||||
{
|
||||
m_factory.add(host_arena::make_unique<factory::library_element_t>(name, std::move(props)));
|
||||
m_factory.add(plib::make_unique<factory::library_element_t, host_arena>(name, std::move(props)));
|
||||
}
|
||||
|
||||
void nlparse_t::register_frontier(const pstring &attach, const pstring &r_IN,
|
||||
@ -508,7 +508,7 @@ pstring setup_t::resolve_alias(const pstring &name) const
|
||||
ret = temp;
|
||||
auto p = m_abstract.m_alias.find(ret);
|
||||
temp = (p != m_abstract.m_alias.end() ? p->second : "");
|
||||
} while (temp != "" && temp != ret);
|
||||
} while (!temp.empty() && temp != ret);
|
||||
|
||||
log().debug("{1}==>{2}\n", name, ret);
|
||||
return ret;
|
||||
@ -532,7 +532,7 @@ pstring setup_t::de_alias(const pstring &alias) const
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (temp != "" && temp != ret);
|
||||
} while (!temp.empty() && temp != ret);
|
||||
|
||||
log().debug("{1}==>{2}\n", alias, ret);
|
||||
return ret;
|
||||
@ -650,7 +650,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(const detail::core_terminal_t &o
|
||||
{
|
||||
nl_assert(out.is_logic());
|
||||
|
||||
const auto &out_cast = static_cast<const logic_output_t &>(out);
|
||||
const auto &out_cast = dynamic_cast<const logic_output_t &>(out);
|
||||
auto iter_proxy(m_proxies.find(&out));
|
||||
|
||||
if (iter_proxy != m_proxies.end())
|
||||
@ -878,7 +878,7 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1,detail::core_termina
|
||||
{
|
||||
log().debug("adding analog net ...\n");
|
||||
// FIXME: Nets should have a unique name
|
||||
auto anet = nlstate().pool().make_owned<analog_net_t>(m_nlstate,"net." + t1.name());
|
||||
auto anet = plib::make_owned<analog_net_t>(nlstate().pool(), m_nlstate,"net." + t1.name());
|
||||
auto *anetp = anet.get();
|
||||
m_nlstate.register_net(std::move(anet));
|
||||
t1.set_net(anetp);
|
||||
@ -1043,7 +1043,7 @@ void setup_t::resolve_inputs()
|
||||
detail::core_terminal_t *t1 = find_terminal(t1s);
|
||||
detail::core_terminal_t *t2 = find_terminal(t2s);
|
||||
if (connect(*t1, *t2))
|
||||
m_abstract.m_links.erase(m_abstract.m_links.begin() + static_cast<std::ptrdiff_t>(i));
|
||||
m_abstract.m_links.erase(m_abstract.m_links.begin() + plib::narrow_cast<std::ptrdiff_t>(i));
|
||||
else
|
||||
i++;
|
||||
}
|
||||
@ -1104,16 +1104,16 @@ void setup_t::resolve_inputs()
|
||||
detail::core_terminal_t *term = i.second;
|
||||
if (term->is_tristate_output())
|
||||
{
|
||||
const auto *tri(static_cast<tristate_output_t *>(term));
|
||||
const auto &tri(dynamic_cast<tristate_output_t &>(*term));
|
||||
// check if we are connected to a proxy
|
||||
const auto iter_proxy(m_proxies.find(tri));
|
||||
const auto iter_proxy(m_proxies.find(&tri));
|
||||
|
||||
if (iter_proxy == m_proxies.end() && !tri->is_force_logic())
|
||||
if (iter_proxy == m_proxies.end() && !tri.is_force_logic())
|
||||
{
|
||||
log().error(ME_TRISTATE_NO_PROXY_FOUND_2(term->name(), term->device().name()));
|
||||
err = true;
|
||||
}
|
||||
else if (iter_proxy != m_proxies.end() && tri->is_force_logic())
|
||||
else if (iter_proxy != m_proxies.end() && tri.is_force_logic())
|
||||
{
|
||||
log().error(ME_TRISTATE_PROXY_FOUND_2(term->name(), term->device().name()));
|
||||
err = true;
|
||||
@ -1256,7 +1256,7 @@ nl_fptype models_t::model_t::value(const pstring &entity) const
|
||||
pstring tmp = value_str(entity);
|
||||
|
||||
nl_fptype factor = nlconst::one();
|
||||
auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
|
||||
auto p = std::next(tmp.begin(), plib::narrow_cast<pstring::difference_type>(tmp.size() - 1));
|
||||
switch (*p)
|
||||
{
|
||||
case 'M': factor = nlconst::magic(1e6); break; // NOLINT
|
||||
@ -1390,7 +1390,7 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
if (it != m_nlstate.family_cache().end())
|
||||
return it->second.get();
|
||||
|
||||
auto ret = host_arena::make_unique<logic_family_std_proxy_t>(ft);
|
||||
auto ret = plib::make_unique<logic_family_std_proxy_t, host_arena>(ft);
|
||||
|
||||
ret->m_low_thresh_PCNT = modv.m_IVL();
|
||||
ret->m_high_thresh_PCNT = modv.m_IVH();
|
||||
@ -1434,7 +1434,7 @@ void setup_t::prepare_to_run()
|
||||
{
|
||||
pstring envlog = plib::util::environment("NL_LOGS", "");
|
||||
|
||||
if (envlog != "")
|
||||
if (!envlog.empty())
|
||||
{
|
||||
std::vector<pstring> loglist(plib::psplit(envlog, ":"));
|
||||
m_parser.register_dynamic_log_devices(loglist);
|
||||
@ -1444,7 +1444,7 @@ void setup_t::prepare_to_run()
|
||||
|
||||
for (auto & e : m_abstract.m_defparams)
|
||||
{
|
||||
auto param(host_arena::make_unique<param_str_t>(nlstate(), e.first, e.second));
|
||||
auto param(plib::make_unique<param_str_t, host_arena>(nlstate(), e.first, e.second));
|
||||
register_param_t(*param);
|
||||
m_defparam_lifetime.push_back(std::move(param));
|
||||
}
|
||||
@ -1597,7 +1597,7 @@ source_string_t::stream_ptr source_string_t::stream(const pstring &name)
|
||||
plib::unused_var(name);
|
||||
auto ret(std::make_unique<std::istringstream>(m_str));
|
||||
ret->imbue(std::locale::classic());
|
||||
return std::move(ret); // FIXME: for c++11 clang builds
|
||||
return ret;
|
||||
}
|
||||
|
||||
source_mem_t::stream_ptr source_mem_t::stream(const pstring &name)
|
||||
@ -1605,7 +1605,7 @@ source_mem_t::stream_ptr source_mem_t::stream(const pstring &name)
|
||||
plib::unused_var(name);
|
||||
auto ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary));
|
||||
ret->imbue(std::locale::classic());
|
||||
return std::move(ret); // FIXME: for c++11 clang builds
|
||||
return ret;
|
||||
}
|
||||
|
||||
source_file_t::stream_ptr source_file_t::stream(const pstring &name)
|
||||
|
@ -307,10 +307,10 @@ namespace netlist
|
||||
void register_param(const pstring ¶m, nl_fptype value);
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<plib::is_floating_point<T>::value || plib::is_integral<T>::value>
|
||||
std::enable_if_t<plib::is_arithmetic<T>::value>
|
||||
register_param_val(const pstring ¶m, T value)
|
||||
{
|
||||
register_param(param, static_cast<nl_fptype>(value));
|
||||
register_param(param, plib::narrow_cast<nl_fptype>(value));
|
||||
}
|
||||
|
||||
void register_lib_entry(const pstring &name, factory::properties &&props);
|
||||
|
@ -78,9 +78,9 @@ namespace netlist
|
||||
/// \note This is not the right location yet.
|
||||
///
|
||||
|
||||
using device_arena = std::conditional<NL_USE_MEMPOOL,
|
||||
using device_arena = std::conditional_t<config::use_mempool::value,
|
||||
plib::mempool_arena<plib::aligned_arena>,
|
||||
plib::aligned_arena>::type;
|
||||
plib::aligned_arena>;
|
||||
using host_arena = plib::aligned_arena;
|
||||
|
||||
/// \brief Interface definition for netlist callbacks into calling code
|
||||
@ -187,7 +187,7 @@ namespace netlist
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief: used define a constant in device description struct
|
||||
/// \brief: used to define a constant in device description struct
|
||||
///
|
||||
/// See the 74125 implementation
|
||||
///
|
||||
|
@ -38,9 +38,9 @@ namespace plib
|
||||
|
||||
mat_precondition_ILU(std::size_t size, std::size_t ilu_scale = 4
|
||||
, std::size_t bw = plib::pmatrix_cr_t<FT, SIZE>::FILL_INFINITY)
|
||||
: m_mat(static_cast<typename mat_type::index_type>(size))
|
||||
, m_LU(static_cast<typename mat_type::index_type>(size))
|
||||
, m_ILU_scale(static_cast<std::size_t>(ilu_scale))
|
||||
: m_mat(narrow_cast<typename mat_type::index_type>(size))
|
||||
, m_LU(narrow_cast<typename mat_type::index_type>(size))
|
||||
, m_ILU_scale(narrow_cast<std::size_t>(ilu_scale))
|
||||
, m_band_width(bw)
|
||||
{
|
||||
}
|
||||
@ -103,7 +103,7 @@ namespace plib
|
||||
if (m_mat.col_idx[k] == i && k < m_mat.row_idx[j+1])
|
||||
nzcol[i].push_back(k);
|
||||
}
|
||||
nzcol[i].push_back(static_cast<std::size_t>(-1));
|
||||
nzcol[i].push_back(narrow_cast<std::size_t>(-1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ namespace plib
|
||||
const auto &nz = nzcol[i];
|
||||
std::size_t j;
|
||||
|
||||
while ((j = nz[nzcolp++])!=static_cast<std::size_t>(-1)) // NOLINT(bugprone-infinite-loop)
|
||||
while ((j = nz[nzcolp++])!=narrow_cast<std::size_t>(-1)) // NOLINT(bugprone-infinite-loop)
|
||||
{
|
||||
v += m_mat.A[j] * m_mat.A[j];
|
||||
}
|
||||
@ -209,14 +209,12 @@ namespace plib
|
||||
// FIXME: hardcoding RESTART to 20 becomes an issue on very large
|
||||
// systems.
|
||||
|
||||
template <typename FT, int SIZE, int RESTART = 80>
|
||||
template <typename FT, int SIZE, int RESTART = 16>
|
||||
struct gmres_t
|
||||
{
|
||||
public:
|
||||
|
||||
using float_type = FT;
|
||||
// FIXME: dirty hack to make this compile
|
||||
static constexpr const std::size_t storage_N = plib::sizeabs<FT, SIZE>::ABS();
|
||||
|
||||
explicit gmres_t(std::size_t size)
|
||||
: residual(size)
|
||||
@ -236,7 +234,7 @@ namespace plib
|
||||
g1 = s * g0_last + c * g1;
|
||||
}
|
||||
|
||||
std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
|
||||
std::size_t size() const { return (SIZE<=0) ? m_size : narrow_cast<std::size_t>(SIZE); }
|
||||
|
||||
template <int k, typename OPS, typename VT>
|
||||
bool do_k(OPS &ops, VT &x, std::size_t &itr_used, FT rho_delta, bool dummy)
|
||||
@ -360,7 +358,7 @@ namespace plib
|
||||
rho_delta = accuracy * rho_to_accuracy;
|
||||
}
|
||||
else
|
||||
rho_delta = accuracy * plib::sqrt(static_cast<FT>(n));
|
||||
rho_delta = accuracy * plib::sqrt(narrow_cast<FT>(n));
|
||||
|
||||
//
|
||||
// Using
|
||||
@ -407,8 +405,6 @@ namespace plib
|
||||
|
||||
private:
|
||||
|
||||
//typedef typename plib::mat_cr_t<FT, SIZE>::index_type mattype;
|
||||
|
||||
plib::parray<float_type, SIZE> residual;
|
||||
plib::parray<float_type, SIZE> Ax;
|
||||
|
||||
@ -423,8 +419,6 @@ namespace plib
|
||||
std::size_t m_size;
|
||||
|
||||
bool m_use_more_precise_stop_condition;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -454,7 +448,7 @@ namespace plib
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
|
||||
std::size_t size() const { return (SIZE<=0) ? m_size : narrow_cast<std::size_t>(SIZE); }
|
||||
|
||||
template <typename OPS, typename VT, typename VRHS>
|
||||
std::size_t solve(OPS &ops, VT &x0, const VRHS & rhs, const std::size_t iter_max, float_type accuracy)
|
||||
@ -478,7 +472,7 @@ namespace plib
|
||||
ops.calc_rhs(Ax, x);
|
||||
vec_sub(size(), rhs, Ax, residual);
|
||||
|
||||
FT rho_delta = accuracy * std::sqrt(static_cast<FT>(size()));
|
||||
FT rho_delta = accuracy * std::sqrt(narrow_cast<FT>(size()));
|
||||
|
||||
rho_delta = 1e-9;
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace plib
|
||||
|
||||
~pmatrix_cr_t() = default;
|
||||
|
||||
constexpr std::size_t size() const noexcept { return (N>0) ? static_cast<std::size_t>(N) : m_size; }
|
||||
constexpr std::size_t size() const noexcept { return (N>0) ? narrow_cast<std::size_t>(N) : m_size; }
|
||||
|
||||
void clear() noexcept
|
||||
{
|
||||
@ -132,9 +132,9 @@ namespace plib
|
||||
row_idx[k] = nz;
|
||||
|
||||
for (std::size_t j=0; j < size(); j++)
|
||||
if (f[k][j] <= max_fill && plib::abs(static_cast<int>(k)-static_cast<int>(j)) <= static_cast<int>(band_width))
|
||||
if (f[k][j] <= max_fill && plib::abs(narrow_cast<int>(k)-narrow_cast<int>(j)) <= narrow_cast<int>(band_width))
|
||||
{
|
||||
col_idx[nz] = static_cast<C>(j);
|
||||
col_idx[nz] = narrow_cast<C>(j);
|
||||
if (j == k)
|
||||
diag[k] = nz;
|
||||
nz++;
|
||||
@ -150,7 +150,7 @@ namespace plib
|
||||
{
|
||||
for (std::size_t j=k + 1; j < size(); j++)
|
||||
if (f[j][k] < FILL_INFINITY)
|
||||
nzbd[k].push_back(static_cast<C>(j));
|
||||
nzbd[k].push_back(narrow_cast<C>(j));
|
||||
nzbd[k].push_back(0); // end of sequence
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ namespace plib
|
||||
{
|
||||
for (std::size_t i = 0; i < m_ge_par.size(); i++)
|
||||
if (plib::container::contains( m_ge_par[i], k))
|
||||
return static_cast<int>(i);
|
||||
return narrow_cast<int>(i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -525,7 +525,7 @@ namespace plib
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
ilu_rows[p++] = static_cast<index_type>(i);
|
||||
ilu_rows[p++] = narrow_cast<index_type>(i);
|
||||
}
|
||||
ilu_rows[p] = 0; // end of array
|
||||
this->build_from_fill_mat(fill, ilup); //, m_band_width); // ILU(2)
|
||||
|
@ -9,6 +9,7 @@
|
||||
///
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pgsl.h"
|
||||
#include "pmath.h"
|
||||
#include "pstring.h"
|
||||
#include "ptypes.h"
|
||||
@ -26,28 +27,52 @@
|
||||
|
||||
namespace plib {
|
||||
|
||||
//============================================================
|
||||
// aligned types
|
||||
//============================================================
|
||||
|
||||
#if 0
|
||||
#if (PUSE_ALIGNED_HINTS)
|
||||
template <typename T, std::size_t A>
|
||||
using aligned_type __attribute__((aligned(A))) = T;
|
||||
#else
|
||||
template <typename T, std::size_t A>
|
||||
using aligned_type = T;
|
||||
#endif
|
||||
|
||||
template <typename T, std::size_t A>
|
||||
using aligned_pointer = aligned_type<T, A> *;
|
||||
|
||||
template <typename T, std::size_t A>
|
||||
using const_aligned_pointer = const aligned_type<T, A> *;
|
||||
|
||||
template <typename T, std::size_t A>
|
||||
using aligned_reference = aligned_type<T, A> &;
|
||||
|
||||
template <typename T, std::size_t A>
|
||||
using const_aligned_reference = const aligned_type<T, A> &;
|
||||
#endif
|
||||
//============================================================
|
||||
// Standard arena_deleter
|
||||
//============================================================
|
||||
|
||||
template <typename P, typename T, typename A = void>
|
||||
struct arena_deleter
|
||||
template <typename P, typename T, bool X>
|
||||
struct arena_deleter_base
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename P, typename T>
|
||||
struct arena_deleter<P, T, std::enable_if_t<!P::has_static_deallocator>>
|
||||
struct arena_deleter_base<P, T, false>
|
||||
{
|
||||
using arena_storage_type = P;
|
||||
|
||||
constexpr arena_deleter(arena_storage_type *a = nullptr) noexcept
|
||||
constexpr arena_deleter_base(arena_storage_type *a = nullptr) noexcept
|
||||
: m_a(a) { }
|
||||
|
||||
template<typename U, typename =
|
||||
std::enable_if_t<std::is_convertible< U*, T*>::value>>
|
||||
arena_deleter(const arena_deleter<P, U> &rhs) noexcept
|
||||
arena_deleter_base(const arena_deleter_base<P, U, false> &rhs) noexcept
|
||||
: m_a(rhs.m_a) { }
|
||||
|
||||
void operator()(T *p) noexcept
|
||||
@ -61,18 +86,18 @@ namespace plib {
|
||||
};
|
||||
|
||||
template <typename P, typename T>
|
||||
struct arena_deleter<P, T, std::enable_if_t<P::has_static_deallocator>>
|
||||
struct arena_deleter_base<P, T, true>
|
||||
{
|
||||
using arena_storage_type = P;
|
||||
|
||||
constexpr arena_deleter(arena_storage_type *a = nullptr) noexcept
|
||||
constexpr arena_deleter_base(arena_storage_type *a = nullptr) noexcept
|
||||
{
|
||||
plib::unused_var(a);
|
||||
}
|
||||
|
||||
template<typename U, typename = typename
|
||||
std::enable_if<std::is_convertible< U*, T*>::value>::type>
|
||||
arena_deleter(const arena_deleter<P, U> &rhs) noexcept
|
||||
arena_deleter_base(const arena_deleter_base<P, U, true> &rhs) noexcept
|
||||
{
|
||||
plib::unused_var(rhs);
|
||||
}
|
||||
@ -85,6 +110,13 @@ namespace plib {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P, typename T>
|
||||
struct arena_deleter : public arena_deleter_base<P, T, P::has_static_deallocator>
|
||||
{
|
||||
using base_type = arena_deleter_base<P, T, P::has_static_deallocator>;
|
||||
using base_type::base_type;
|
||||
};
|
||||
|
||||
//============================================================
|
||||
// owned_ptr: smart pointer with ownership information
|
||||
//============================================================
|
||||
@ -209,7 +241,8 @@ namespace plib {
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
static constexpr const std::size_t align_size = ALIGN;
|
||||
using pointer = T *;
|
||||
static /*constexpr*/ const std::size_t align_size = ALIGN;
|
||||
using arena_type = ARENA;
|
||||
|
||||
static_assert(align_size >= alignof(T) && (align_size % alignof(T)) == 0,
|
||||
@ -237,14 +270,14 @@ namespace plib {
|
||||
using other = arena_allocator<ARENA, U, ALIGN>;
|
||||
};
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
pointer allocate(std::size_t n)
|
||||
{
|
||||
return reinterpret_cast<T *>(m_a.allocate(ALIGN, sizeof(T) * n)); //NOLINT
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n) noexcept
|
||||
void deallocate(pointer p, std::size_t n) noexcept
|
||||
{
|
||||
m_a.deallocate(p, n);
|
||||
m_a.deallocate(p, sizeof(T) * n);
|
||||
}
|
||||
|
||||
template<typename U, typename... Args>
|
||||
@ -296,171 +329,88 @@ namespace plib {
|
||||
// The previous code compiled with gcc and clang on all platforms and
|
||||
// compilers apart from MSVC.
|
||||
|
||||
template <typename P, bool HSD>
|
||||
template <typename P, bool HSD, bool HSA>
|
||||
struct arena_base;
|
||||
|
||||
template <typename P, bool HSD, bool HSA>
|
||||
struct arena_core
|
||||
{
|
||||
static constexpr const bool has_static_deallocator = HSD;
|
||||
static constexpr const bool has_static_allocator = HSA;
|
||||
using size_type = std::size_t;
|
||||
|
||||
template <class T, size_type ALIGN = alignof(T)>
|
||||
using allocator_type = arena_allocator<P, T, ALIGN>;
|
||||
|
||||
template <class T>
|
||||
using deleter_type = arena_deleter<P, T>;
|
||||
|
||||
template <typename T>
|
||||
using unique_ptr = std::unique_ptr<T, deleter_type<T>>;
|
||||
|
||||
template <typename T>
|
||||
using owned_ptr = plib::owned_ptr<T, deleter_type<T>>;
|
||||
|
||||
static inline P &instance() noexcept
|
||||
{
|
||||
static P s_arena;
|
||||
return s_arena;
|
||||
}
|
||||
|
||||
size_type cur_alloc() const noexcept { return m_stat_cur_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
|
||||
size_type max_alloc() const noexcept { return m_stat_max_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
|
||||
protected:
|
||||
static size_t &m_stat_cur_alloc() noexcept { static size_t val = 0; return val; }
|
||||
static size_t &m_stat_max_alloc() noexcept { static size_t val = 0; return val; }
|
||||
friend struct arena_base<P, HSD, HSA>;
|
||||
private:
|
||||
size_t m_stat_cur_alloc = 0;
|
||||
size_t m_stat_max_alloc = 0;
|
||||
|
||||
};
|
||||
|
||||
template <typename P, bool HSD>
|
||||
struct arena_hsd : public arena_core<P, HSD>
|
||||
template <typename P, bool HSD, bool HSA>
|
||||
struct arena_base : public arena_core<P, HSD, HSA>
|
||||
{
|
||||
template<typename T>
|
||||
inline void free(T *ptr) noexcept
|
||||
using base_type = arena_core<P, HSD, HSA>;
|
||||
using size_type = typename base_type::size_type;
|
||||
|
||||
static size_type cur_alloc() noexcept { return base_type::instance().m_stat_cur_alloc; }
|
||||
static size_type max_alloc() noexcept { return base_type::instance().m_stat_max_alloc; }
|
||||
|
||||
static inline void inc_alloc_stat(size_type size)
|
||||
{
|
||||
ptr->~T();
|
||||
static_cast<P *>(this)->deallocate(ptr, sizeof(T));
|
||||
auto &i = base_type::instance();
|
||||
i.m_stat_cur_alloc += size;
|
||||
if (i.m_stat_max_alloc <i.m_stat_cur_alloc)
|
||||
i.m_stat_max_alloc = i.m_stat_cur_alloc;
|
||||
}
|
||||
static inline void dec_alloc_stat(size_type size)
|
||||
{
|
||||
base_type::instance().m_stat_cur_alloc -= size;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
struct arena_hsd<P, true> : public arena_core<P, true>
|
||||
struct arena_base<P, false, false> : public arena_core<P, false, false>
|
||||
{
|
||||
template<typename T>
|
||||
static inline void free(T *ptr) noexcept
|
||||
using size_type = typename arena_core<P, false, false>::size_type;
|
||||
|
||||
size_type cur_alloc() const noexcept { return this->m_stat_cur_alloc; }
|
||||
size_type max_alloc() const noexcept { return this->m_stat_max_alloc; }
|
||||
|
||||
inline void inc_alloc_stat(size_type size)
|
||||
{
|
||||
ptr->~T();
|
||||
P::deallocate(ptr, sizeof(T));
|
||||
this->m_stat_cur_alloc += size;
|
||||
if (this->m_stat_max_alloc < this->m_stat_cur_alloc)
|
||||
this->m_stat_max_alloc = this->m_stat_cur_alloc;
|
||||
}
|
||||
inline void dec_alloc_stat(size_type size)
|
||||
{
|
||||
this->m_stat_cur_alloc -= size;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename P, bool HSD, bool HSA>
|
||||
struct arena_base : public arena_hsd<P, HSD>
|
||||
{
|
||||
template <class T>
|
||||
using deleter_type = arena_deleter<P, T>;
|
||||
|
||||
template <typename T>
|
||||
using unique_ptr = std::unique_ptr<T, deleter_type<T>>;
|
||||
|
||||
template <typename T>
|
||||
using owned_ptr = plib::owned_ptr<T, deleter_type<T>>;
|
||||
|
||||
template<typename T, typename... Args>
|
||||
inline unique_ptr<T> make_unique(Args&&... args)
|
||||
{
|
||||
auto *mem = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
auto *mema = new (mem) T(std::forward<Args>(args)...);
|
||||
return unique_ptr<T>(mema, deleter_type<T>());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
static_cast<P *>(this)->deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
inline owned_ptr<T> make_owned(Args&&... args)
|
||||
{
|
||||
auto *mem = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
auto *mema = new (mem) T(std::forward<Args>(args)...);
|
||||
return owned_ptr<T>(mema, true, deleter_type<T>());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
static_cast<P *>(this)->deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
inline T * alloc(Args&&... args)
|
||||
{
|
||||
auto *p = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
return new(p) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename P, bool HSD>
|
||||
struct arena_base<P, HSD, true> : public arena_hsd<P, HSD>
|
||||
{
|
||||
template <class T>
|
||||
using deleter_type = arena_deleter<P, T>;
|
||||
|
||||
template <typename T>
|
||||
using unique_ptr = std::unique_ptr<T, deleter_type<T>>;
|
||||
|
||||
template <typename T>
|
||||
using owned_ptr = plib::owned_ptr<T, deleter_type<T>>;
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static inline unique_ptr<T> make_unique(Args&&... args)
|
||||
{
|
||||
auto *mem = P::allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
auto *mema = new (mem) T(std::forward<Args>(args)...);
|
||||
return unique_ptr<T>(mema, deleter_type<T>());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
P::deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static inline owned_ptr<T> make_owned(Args&&... args)
|
||||
{
|
||||
auto *mem = P::allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
auto *mema = new (mem) T(std::forward<Args>(args)...);
|
||||
return owned_ptr<T>(mema, true, deleter_type<T>());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
P::deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static inline T * alloc(Args&&... args)
|
||||
{
|
||||
auto *p = P::allocate(alignof(T), sizeof(T));
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
return new(p) T(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct aligned_arena : public arena_base<aligned_arena, true, true>
|
||||
{
|
||||
static inline void *allocate( size_t alignment, size_t size )
|
||||
static inline gsl::owner<void *> allocate( size_t alignment, size_t size )
|
||||
{
|
||||
m_stat_cur_alloc() += size;
|
||||
if (m_stat_max_alloc() < m_stat_cur_alloc())
|
||||
m_stat_max_alloc() = m_stat_cur_alloc();
|
||||
inc_alloc_stat(size);
|
||||
|
||||
#if (PUSE_ALIGNED_ALLOCATION)
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
@ -472,7 +422,7 @@ namespace plib {
|
||||
}
|
||||
return p;
|
||||
#else
|
||||
return aligned_alloc(alignment, size);
|
||||
return static_cast<gsl::owner<void *>>(aligned_alloc(alignment, size));
|
||||
#endif
|
||||
#else
|
||||
unused_var(alignment);
|
||||
@ -480,10 +430,10 @@ namespace plib {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void deallocate( void *ptr, size_t size ) noexcept
|
||||
static inline void deallocate(gsl::owner<void *> ptr, size_t size ) noexcept
|
||||
{
|
||||
//unused_var(size);
|
||||
m_stat_cur_alloc() -= size;
|
||||
dec_alloc_stat(size);
|
||||
#if (PUSE_ALIGNED_ALLOCATION)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
|
||||
::free(ptr);
|
||||
@ -504,14 +454,14 @@ namespace plib {
|
||||
{
|
||||
static inline void *allocate( size_t alignment, size_t size )
|
||||
{
|
||||
m_stat_cur_alloc() += size;
|
||||
inc_alloc_stat(size);
|
||||
unused_var(alignment);
|
||||
return ::operator new(size);
|
||||
}
|
||||
|
||||
static inline void deallocate( void *ptr, size_t size ) noexcept
|
||||
{
|
||||
m_stat_cur_alloc() -= size;
|
||||
dec_alloc_stat(size);
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
@ -522,31 +472,116 @@ namespace plib {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t ALIGN>
|
||||
constexpr T *assume_aligned_ptr(T *p) noexcept
|
||||
namespace detail
|
||||
{
|
||||
static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
|
||||
static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline T * alloc(Args&&... args)
|
||||
{
|
||||
auto *mem = ARENA::allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
return new (mem) T(std::forward<Args>(args)...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ARENA::deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#if (PUSE_ALIGNED_HINTS)
|
||||
return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
|
||||
#else
|
||||
return p;
|
||||
#endif
|
||||
template<typename ARENA, typename T>
|
||||
static inline void free(T *ptr) noexcept
|
||||
{
|
||||
ptr->~T();
|
||||
ARENA::deallocate(ptr, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline T * alloc(ARENA &arena, Args&&... args)
|
||||
{
|
||||
auto *mem = arena.allocate(alignof(T), sizeof(T));
|
||||
try
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
return new (mem) T(std::forward<Args>(args)...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
arena.deallocate(mem, sizeof(T));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ARENA, typename T>
|
||||
static inline void free(ARENA &arena, T *ptr) noexcept
|
||||
{
|
||||
ptr->~T();
|
||||
arena.deallocate(ptr, sizeof(T));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline
|
||||
std::enable_if_t<ARENA::has_static_allocator, typename ARENA::template unique_ptr<T>>
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
using up_type = typename ARENA::template unique_ptr<T>;
|
||||
using deleter_type = typename ARENA::template deleter_type<T>;
|
||||
auto *mem = detail::alloc<T, ARENA>(std::forward<Args>(args)...);
|
||||
return up_type(mem, deleter_type());
|
||||
}
|
||||
|
||||
template <typename T, std::size_t ALIGN>
|
||||
constexpr const T *assume_aligned_ptr(const T *p) noexcept
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline
|
||||
std::enable_if_t<!ARENA::has_static_allocator, typename ARENA::template unique_ptr<T>>
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
|
||||
static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
|
||||
#if (PUSE_ALIGNED_HINTS)
|
||||
return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN));
|
||||
#else
|
||||
return p;
|
||||
#endif
|
||||
return make_unique<T>(ARENA::instance(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline
|
||||
typename ARENA::template unique_ptr<T>
|
||||
make_unique(ARENA &arena, Args&&... args)
|
||||
{
|
||||
using up_type = typename ARENA::template unique_ptr<T>;
|
||||
using deleter_type = typename ARENA::template deleter_type<T>;
|
||||
auto *mem = detail::alloc<T>(arena, std::forward<Args>(args)...);
|
||||
return up_type(mem, deleter_type(&arena));
|
||||
}
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline
|
||||
std::enable_if_t<ARENA::has_static_allocator, typename ARENA::template owned_ptr<T>>
|
||||
make_owned(Args&&... args)
|
||||
{
|
||||
using op_type = typename ARENA::template owned_ptr<T>;
|
||||
using deleter_type = typename ARENA::template deleter_type<T>;
|
||||
auto *mem = detail::alloc<T, ARENA>(std::forward<Args>(args)...);
|
||||
return op_type(mem, true, deleter_type());
|
||||
}
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline
|
||||
std::enable_if_t<!ARENA::has_static_allocator, typename ARENA::template owned_ptr<T>>
|
||||
make_owned(Args&&... args)
|
||||
{
|
||||
return make_owned<T>(ARENA::instance(), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename ARENA, typename... Args>
|
||||
static inline typename ARENA::template owned_ptr<T> make_owned(ARENA &arena, Args&&... args)
|
||||
{
|
||||
using op_type = typename ARENA::template owned_ptr<T>;
|
||||
using deleter_type = typename ARENA::template deleter_type<T>;
|
||||
auto *mem = detail::alloc<T>(arena, std::forward<Args>(args)...);
|
||||
return op_type(mem, true, deleter_type(&arena));
|
||||
}
|
||||
|
||||
|
||||
template <class T, std::size_t ALIGN = alignof(T)>
|
||||
using aligned_allocator = aligned_arena::allocator_type<T, ALIGN>;
|
||||
|
||||
@ -557,57 +592,72 @@ namespace plib {
|
||||
|
||||
PDEFINE_HAS_MEMBER(has_align, align_size);
|
||||
|
||||
template <typename T, typename X = void>
|
||||
struct align_traits
|
||||
template <typename T, bool X>
|
||||
struct align_traits_base
|
||||
{
|
||||
static_assert(!has_align<T>::value, "no align");
|
||||
static constexpr const std::size_t align_size = alignof(std::max_align_t);
|
||||
static constexpr const std::size_t value_size = sizeof(typename T::value_type);
|
||||
static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct align_traits<T, std::enable_if_t<has_align<T>::value, void>>
|
||||
struct align_traits_base<T, true>
|
||||
{
|
||||
static_assert(has_align<T>::value, "no align");
|
||||
static constexpr const std::size_t align_size = T::align_size;
|
||||
static constexpr const std::size_t value_size = sizeof(typename T::value_type);
|
||||
static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct align_traits : public align_traits_base<T, has_align<T>::value>
|
||||
{};
|
||||
|
||||
template <typename BASEARENA = aligned_arena, std::size_t PAGESIZE = 1024>
|
||||
class paged_arena : public arena_base<paged_arena<BASEARENA, PAGESIZE>, true, true>
|
||||
{
|
||||
public:
|
||||
paged_arena()
|
||||
{
|
||||
}
|
||||
|
||||
PCOPYASSIGNMOVE(paged_arena, delete)
|
||||
|
||||
~paged_arena() = default;
|
||||
|
||||
static void *allocate(size_t align, size_t size)
|
||||
{
|
||||
plib::unused_var(align);
|
||||
//size = ((size + PAGESIZE - 1) / PAGESIZE) * PAGESIZE;
|
||||
return arena().allocate(PAGESIZE, size);
|
||||
}
|
||||
|
||||
static void deallocate(void *ptr, size_t size) noexcept
|
||||
{
|
||||
//size = ((size + PAGESIZE - 1) / PAGESIZE) * PAGESIZE;
|
||||
arena().deallocate(ptr, size);
|
||||
}
|
||||
|
||||
bool operator ==(const paged_arena &rhs) const noexcept { return this == &rhs; }
|
||||
|
||||
static BASEARENA &arena() noexcept { static BASEARENA m_arena; return m_arena; }
|
||||
private:
|
||||
};
|
||||
|
||||
//============================================================
|
||||
// Aligned vector
|
||||
//============================================================
|
||||
|
||||
// FIXME: needs a separate file
|
||||
template <typename T, std::size_t ALIGN = PALIGN_VECTOROPT, typename A = aligned_allocator<T, ALIGN>>
|
||||
class aligned_vector : public std::vector<T, A>
|
||||
template <typename T, std::size_t ALIGN = PALIGN_VECTOROPT, typename A = paged_arena<>>//aligned_arena>
|
||||
class aligned_vector : public std::vector<T, typename A::template allocator_type<T, ALIGN>>
|
||||
{
|
||||
public:
|
||||
using base = std::vector<T, A>;
|
||||
|
||||
using reference = typename base::reference;
|
||||
using const_reference = typename base::const_reference;
|
||||
using pointer = typename base::pointer;
|
||||
using const_pointer = typename base::const_pointer;
|
||||
using size_type = typename base::size_type;
|
||||
using base = std::vector<T, typename A::template allocator_type<T, ALIGN>>;
|
||||
|
||||
using base::base;
|
||||
|
||||
base & as_base() noexcept { return *this; }
|
||||
const base & as_base() const noexcept { return *this; }
|
||||
|
||||
constexpr reference operator[](size_type i) noexcept
|
||||
{
|
||||
return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type i) const noexcept
|
||||
{
|
||||
return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
|
||||
}
|
||||
|
||||
pointer data() noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
|
||||
const_pointer data() const noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
|
||||
|
||||
};
|
||||
|
||||
} // namespace plib
|
||||
|
@ -21,19 +21,20 @@
|
||||
|
||||
namespace plib {
|
||||
|
||||
template <typename FT, int SIZE>
|
||||
template <typename FT, int SIZE, typename ARENA>
|
||||
struct sizeabs
|
||||
{
|
||||
static constexpr std::size_t ABS() noexcept { return (SIZE < 0) ? static_cast<std::size_t>(0 - SIZE) : static_cast<std::size_t>(SIZE); }
|
||||
static constexpr std::size_t ABS() noexcept { return (SIZE < 0) ? narrow_cast<std::size_t>(0 - SIZE) : narrow_cast<std::size_t>(SIZE); }
|
||||
using container = typename std::array<FT, ABS()> ;
|
||||
};
|
||||
|
||||
template <typename FT>
|
||||
struct sizeabs<FT, 0>
|
||||
template <typename FT, typename ARENA>
|
||||
struct sizeabs<FT, 0, ARENA>
|
||||
{
|
||||
static constexpr std::size_t ABS() noexcept { return 0; }
|
||||
using allocator_type = typename ARENA::template allocator_type<FT, PALIGN_VECTOROPT>;
|
||||
//using container = typename std::vector<FT, arena_allocator<mempool, FT, 64>>;
|
||||
using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
|
||||
using container = typename std::vector<FT, allocator_type>;
|
||||
};
|
||||
|
||||
/// \brief Array with preallocated or dynamic allocation.
|
||||
@ -51,17 +52,20 @@ namespace plib {
|
||||
/// I consider > 10% performance difference to be a use case.
|
||||
///
|
||||
|
||||
template <typename FT, int SIZE>
|
||||
template <typename FT, int SIZE, typename ARENA = aligned_arena>
|
||||
struct parray
|
||||
{
|
||||
public:
|
||||
static constexpr std::size_t SIZEABS() noexcept { return sizeabs<FT, SIZE>::ABS(); }
|
||||
static constexpr std::size_t SIZEABS() noexcept { return sizeabs<FT, SIZE, ARENA>::ABS(); }
|
||||
|
||||
using base_type = typename sizeabs<FT, SIZE>::container;
|
||||
using base_type = typename sizeabs<FT, SIZE, ARENA>::container;
|
||||
using size_type = typename base_type::size_type;
|
||||
using reference = typename base_type::reference;
|
||||
using const_reference = typename base_type::const_reference;
|
||||
using value_type = typename base_type::value_type;
|
||||
using value_type = FT;
|
||||
using reference = FT &;
|
||||
using const_reference = const FT &;
|
||||
|
||||
using pointer = FT *;
|
||||
using const_pointer = const FT *;
|
||||
|
||||
template <int X = SIZE >
|
||||
parray(size_type size, std::enable_if_t<(X==0), int> = 0)
|
||||
@ -70,7 +74,7 @@ namespace plib {
|
||||
}
|
||||
|
||||
template <int X = SIZE >
|
||||
parray(size_type size, FT val, std::enable_if_t<(X==0), int> = 0)
|
||||
parray(size_type size, const FT &val, std::enable_if_t<(X==0), int> = 0)
|
||||
: m_a(size, val), m_size(size)
|
||||
{
|
||||
}
|
||||
@ -85,7 +89,7 @@ namespace plib {
|
||||
}
|
||||
|
||||
template <int X = SIZE >
|
||||
parray(size_type size, FT val, std::enable_if_t<(X != 0), int> = 0) noexcept(false)
|
||||
parray(size_type size, const FT &val, std::enable_if_t<(X != 0), int> = 0) noexcept(false)
|
||||
: m_size(size)
|
||||
{
|
||||
if ((SIZE < 0 && size > SIZEABS())
|
||||
@ -131,20 +135,19 @@ namespace plib {
|
||||
|
||||
constexpr reference operator[](size_type i) noexcept
|
||||
{
|
||||
return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
|
||||
return data()[i];
|
||||
}
|
||||
constexpr const_reference operator[](size_type i) const noexcept
|
||||
{
|
||||
return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
|
||||
return data()[i];
|
||||
}
|
||||
|
||||
FT * data() noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
|
||||
const FT * data() const noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
|
||||
pointer data() noexcept { return m_a.data(); }
|
||||
const_pointer data() const noexcept { return m_a.data(); }
|
||||
|
||||
private:
|
||||
PALIGNAS_VECTOROPT()
|
||||
base_type m_a;
|
||||
PALIGNAS_CACHELINE()
|
||||
size_type m_size;
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
///
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pgsl.h"
|
||||
#include "ptypes.h"
|
||||
|
||||
#include <chrono>
|
||||
@ -212,8 +213,8 @@ namespace plib {
|
||||
ctype count() const noexcept { return m_count; }
|
||||
|
||||
template <typename S>
|
||||
S as_seconds() const noexcept { return static_cast<S>(total())
|
||||
/ static_cast<S>(T::per_second()); }
|
||||
S as_seconds() const noexcept { return narrow_cast<S>(total())
|
||||
/ narrow_cast<S>(T::per_second()); }
|
||||
|
||||
guard_t guard() noexcept { return guard_t(*this); }
|
||||
private:
|
||||
@ -244,7 +245,7 @@ namespace plib {
|
||||
constexpr type total() const noexcept { return 0; }
|
||||
constexpr ctype count() const noexcept { return 0; }
|
||||
template <typename S>
|
||||
S as_seconds() const noexcept { return static_cast<S>(0.0); }
|
||||
S as_seconds() const noexcept { return narrow_cast<S>(0); }
|
||||
constexpr static bool enabled = false;
|
||||
guard_t guard() { return guard_t(); }
|
||||
};
|
||||
|
@ -72,10 +72,11 @@
|
||||
#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE)
|
||||
#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT)
|
||||
|
||||
// FIXME: Breaks mame build on windows due to -Wattribute
|
||||
// FIXME: Breaks mame build on windows mingw due to -Wattribute
|
||||
// also triggers -Wattribute on ARM
|
||||
// This is fixed on mingw version 10
|
||||
// FIXME: no error on cross-compile - need further checks
|
||||
#if defined(__GNUC__) && (defined(_WIN32) || defined(__arm__) || defined(__ARMEL__))
|
||||
#if defined(__GNUC__) && ((defined(_WIN32) && __GNUC__ < 10) || defined(__arm__) || defined(__ARMEL__))
|
||||
#define PALIGNAS(x)
|
||||
#else
|
||||
#define PALIGNAS(x) alignas(x)
|
||||
@ -83,7 +84,7 @@
|
||||
|
||||
/// \brief nvcc build flag.
|
||||
///
|
||||
/// Set this to 1 if you are building with NVIDIA nvcc
|
||||
/// Set this to 101 if you are building with NVIDIA nvcc 10.1
|
||||
///
|
||||
#ifndef NVCCBUILD
|
||||
#define NVCCBUILD (0)
|
||||
@ -166,5 +167,15 @@ typedef __float128 FLOAT128;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (PUSE_FLOAT128)
|
||||
#if defined(__has_include)
|
||||
#if !__has_include(<quadmath.h>)
|
||||
//#pragma message "disabling PUSE_FLOAT128 due to missing quadmath.h"
|
||||
#undef PUSE_FLOAT128
|
||||
#define PUSE_FLOAT128 (0)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif // PCONFIG_H_
|
||||
|
@ -31,6 +31,7 @@ namespace plib {
|
||||
template <typename T>
|
||||
T getsym(const pstring &name) const noexcept
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return reinterpret_cast<T>(getsym_p(name));
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace plib
|
||||
// Implementation in putil.cpp.
|
||||
// Putting the code here leads to a performance decrease.
|
||||
static int from_string_int(const pstring &str, const pstring &x);
|
||||
static pstring nthstr(int n, const pstring &str);
|
||||
static pstring nthstr(std::size_t n, const pstring &str);
|
||||
};
|
||||
|
||||
} // namespace plib
|
||||
@ -34,7 +34,6 @@ namespace plib
|
||||
enum E { __VA_ARGS__ }; \
|
||||
constexpr ename (const E &v) : m_v(v) { } \
|
||||
template <typename T> explicit constexpr ename(const T &val) { m_v = static_cast<E>(val); } \
|
||||
template <typename T> explicit constexpr ename(T && val) { m_v = static_cast<E>(val); } \
|
||||
bool set_from_string (const pstring &s) { \
|
||||
int f = from_string_int(strings(), s); \
|
||||
if (f>=0) { m_v = static_cast<E>(f); return true; } \
|
||||
@ -44,7 +43,7 @@ namespace plib
|
||||
constexpr bool operator==(const ename &rhs) const noexcept {return m_v == rhs.m_v;} \
|
||||
constexpr bool operator==(const E &rhs) const noexcept {return m_v == rhs;} \
|
||||
pstring name() const { \
|
||||
return nthstr(static_cast<int>(m_v), strings()); \
|
||||
return nthstr(m_v, strings()); \
|
||||
} \
|
||||
private: E m_v; \
|
||||
static pstring strings() {\
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "pfmtlog.h"
|
||||
|
||||
#include <cfenv>
|
||||
#include <iostream>
|
||||
#include <cfloat>
|
||||
#include <iostream>
|
||||
|
||||
#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__)
|
||||
#define HAS_FEENABLE_EXCEPT (1)
|
||||
|
@ -92,7 +92,7 @@ pfmt::rtype pfmt::setfmt(std::stringstream &strm, char32_t cfmt_spec)
|
||||
// a.b format here ...
|
||||
char32_t pend(0);
|
||||
int width(0);
|
||||
if (fmt != "" && pstring("duxofge").find(static_cast<pstring::value_type>(cfmt_spec)) != pstring::npos)
|
||||
if (!fmt.empty() && pstring("duxofge").find(static_cast<pstring::value_type>(cfmt_spec)) != pstring::npos)
|
||||
{
|
||||
pend = static_cast<char32_t>(fmt.at(fmt.size() - 1));
|
||||
if (pstring("duxofge").find(static_cast<pstring::value_type>(pend)) == pstring::npos)
|
||||
@ -113,7 +113,7 @@ pfmt::rtype pfmt::setfmt(std::stringstream &strm, char32_t cfmt_spec)
|
||||
strm << std::setprecision(pstonum_ne_def<int>(fmt.substr(pdot + 1), 6));
|
||||
width = pstonum_ne_def<int>(left(fmt,pdot), 0);
|
||||
}
|
||||
else if (fmt != "")
|
||||
else if (!fmt.empty())
|
||||
width = pstonum_ne_def<int>(fmt, 0);
|
||||
|
||||
auto aw(plib::abs(width));
|
||||
|
@ -55,7 +55,7 @@ namespace plib {
|
||||
static char32_t fmt_spec() { return 'f'; }
|
||||
static inline void streamify(std::ostream &s, const FLOAT128 &v)
|
||||
{
|
||||
s << static_cast<long double>(v);
|
||||
s << narrow_cast<long double>(v);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@ -322,7 +322,7 @@ namespace plib {
|
||||
if (build_enabled && enabled && m_enabled)
|
||||
{
|
||||
pfmt pf(fmt);
|
||||
static_cast<T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...));
|
||||
dynamic_cast<T &>(*this).vdowrite(xlog(pf, std::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ namespace plib {
|
||||
if (build_enabled && m_enabled)
|
||||
{
|
||||
pfmt pf(fmt);
|
||||
static_cast<const T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...));
|
||||
static_cast<const T &>(*this).vdowrite(xlog(pf, std::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,26 +25,26 @@ namespace plib {
|
||||
{
|
||||
static std::map<pstring, F> units_si_stat =
|
||||
{
|
||||
//{ "Y", static_cast<F>(1e24) }, // NOLINT: Yotta
|
||||
//{ "Z", static_cast<F>(1e21) }, // NOLINT: Zetta
|
||||
//{ "E", static_cast<F>(1e18) }, // NOLINT: Exa
|
||||
{ "P", static_cast<F>(1e15) }, // NOLINT: Peta
|
||||
{ "T", static_cast<F>(1e12) }, // NOLINT: Tera
|
||||
{ "G", static_cast<F>( 1e9) }, // NOLINT: Giga
|
||||
{ "M", static_cast<F>( 1e6) }, // NOLINT: Mega
|
||||
{ "k", static_cast<F>( 1e3) }, // NOLINT: Kilo
|
||||
{ "h", static_cast<F>( 1e2) }, // NOLINT: Hekto
|
||||
//{ "da", static_cast<F>(1e1) }, // NOLINT: Deka
|
||||
{ "d", static_cast<F>(1e-1) }, // NOLINT: Dezi
|
||||
{ "c", static_cast<F>(1e-2) }, // NOLINT: Zenti
|
||||
{ "m", static_cast<F>(1e-3) }, // NOLINT: Milli
|
||||
{ "μ", static_cast<F>(1e-6) }, // NOLINT: Mikro
|
||||
{ "n", static_cast<F>(1e-9) }, // NOLINT: Nano
|
||||
{ "p", static_cast<F>(1e-12) }, // NOLINT: Piko
|
||||
{ "f", static_cast<F>(1e-15) }, // NOLINT: Femto
|
||||
{ "a", static_cast<F>(1e-18) }, // NOLINT: Atto
|
||||
{ "z", static_cast<F>(1e-21) }, // NOLINT: Zepto
|
||||
{ "y", static_cast<F>(1e-24) }, // NOLINT: Yokto
|
||||
//{ "Y", narrow_cast<F>(1e24) }, // NOLINT: Yotta
|
||||
//{ "Z", narrow_cast<F>(1e21) }, // NOLINT: Zetta
|
||||
//{ "E", narrow_cast<F>(1e18) }, // NOLINT: Exa
|
||||
{ "P", narrow_cast<F>(1e15) }, // NOLINT: Peta
|
||||
{ "T", narrow_cast<F>(1e12) }, // NOLINT: Tera
|
||||
{ "G", narrow_cast<F>( 1e9) }, // NOLINT: Giga
|
||||
{ "M", narrow_cast<F>( 1e6) }, // NOLINT: Mega
|
||||
{ "k", narrow_cast<F>( 1e3) }, // NOLINT: Kilo
|
||||
{ "h", narrow_cast<F>( 1e2) }, // NOLINT: Hekto
|
||||
//{ "da", narrow_cast<F>(1e1) }, // NOLINT: Deka
|
||||
{ "d", narrow_cast<F>(1e-1) }, // NOLINT: Dezi
|
||||
{ "c", narrow_cast<F>(1e-2) }, // NOLINT: Zenti
|
||||
{ "m", narrow_cast<F>(1e-3) }, // NOLINT: Milli
|
||||
{ "μ", narrow_cast<F>(1e-6) }, // NOLINT: Mikro
|
||||
{ "n", narrow_cast<F>(1e-9) }, // NOLINT: Nano
|
||||
{ "p", narrow_cast<F>(1e-12) }, // NOLINT: Piko
|
||||
{ "f", narrow_cast<F>(1e-15) }, // NOLINT: Femto
|
||||
{ "a", narrow_cast<F>(1e-18) }, // NOLINT: Atto
|
||||
{ "z", narrow_cast<F>(1e-21) }, // NOLINT: Zepto
|
||||
{ "y", narrow_cast<F>(1e-24) }, // NOLINT: Yokto
|
||||
};
|
||||
return units_si_stat;
|
||||
}
|
||||
@ -105,7 +105,7 @@ namespace plib {
|
||||
if (inputs[i] == cmd)
|
||||
{
|
||||
rc.m_cmd = PUSH_INPUT;
|
||||
rc.m_param = static_cast<NT>(i);
|
||||
rc.m_param = narrow_cast<NT>(i);
|
||||
stk += 1;
|
||||
break;
|
||||
}
|
||||
@ -128,7 +128,7 @@ namespace plib {
|
||||
}
|
||||
if (stk < 1)
|
||||
throw pexception(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr));
|
||||
if (stk >= static_cast<int>(MAX_STACK))
|
||||
if (stk >= narrow_cast<int>(MAX_STACK))
|
||||
throw pexception(plib::pfmt("pfunction: stack overflow on token <{1}> in <{2}>")(cmd)(expr));
|
||||
m_precompiled.push_back(rc);
|
||||
}
|
||||
@ -286,7 +286,7 @@ namespace plib {
|
||||
lfsr >>= 1;
|
||||
if (lsb)
|
||||
lfsr ^= 0xB400U; // NOLINT: taps 15, 13, 12, 10
|
||||
return static_cast<NT>(lfsr) / static_cast<NT>(0xffffU); // NOLINT
|
||||
return narrow_cast<NT>(lfsr) / narrow_cast<NT>(0xffffU); // NOLINT
|
||||
}
|
||||
|
||||
template <typename NT>
|
||||
@ -297,7 +297,7 @@ namespace plib {
|
||||
lfsr >>= 1;
|
||||
if (lsb)
|
||||
lfsr ^= 0xB400U; // NOLINT: taps 15, 13, 12, 10
|
||||
return static_cast<NT>(lfsr);
|
||||
return narrow_cast<NT>(lfsr);
|
||||
}
|
||||
|
||||
#define ST1 stack[ptr]
|
||||
@ -333,7 +333,7 @@ namespace plib {
|
||||
stack[ptr++] = lfsr_random<value_type>(m_lfsr);
|
||||
break;
|
||||
case PUSH_INPUT:
|
||||
stack[ptr++] = values[static_cast<unsigned>(rc.m_param)];
|
||||
stack[ptr++] = values[narrow_cast<unsigned>(rc.m_param)];
|
||||
break;
|
||||
case PUSH_CONST:
|
||||
stack[ptr++] = rc.m_param;
|
||||
|
105
src/lib/netlist/plib/pgsl.h
Normal file
105
src/lib/netlist/plib/pgsl.h
Normal file
@ -0,0 +1,105 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
#ifndef PGSL_H_
|
||||
#define PGSL_H_
|
||||
|
||||
///
|
||||
/// \file pgsl.h
|
||||
///
|
||||
/// This core guidelines gsl implementation currently provides only enough
|
||||
/// functionality to syntactically support a very limited number of the
|
||||
/// gsl specification.
|
||||
///
|
||||
/// Going forward this approach may be extended.
|
||||
///
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pexception.h"
|
||||
#include "ptypes.h"
|
||||
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#if defined(__has_builtin) // clang and gcc 10
|
||||
#if __has_builtin(__builtin_unreachable)
|
||||
#define gsl_Expects(e) ((e) ? static_cast<void>(0) : __builtin_unreachable())
|
||||
#endif
|
||||
#elif defined(__GNUC__) && !(defined( __CUDACC__ ) && defined( __CUDA_ARCH__ ))
|
||||
#define gsl_Expects(e) ((e) ? static_cast<void>(0) : __builtin_unreachable())
|
||||
#elif defined(_MSC_VER)
|
||||
#define gsl_Expects(e) __assume(e)
|
||||
#else
|
||||
#define gsl_Expects(e) ((e) ? static_cast<void>(0) : static_cast<void>(0))
|
||||
#endif
|
||||
|
||||
#undef gsl_Expects
|
||||
#define gsl_Expects(e) do {} while (0)
|
||||
#define gsl_Ensures(e) gsl_Expects(e)
|
||||
|
||||
namespace plib {
|
||||
namespace pgsl {
|
||||
|
||||
struct narrowing_error : public std::exception {};
|
||||
|
||||
template <typename T>
|
||||
using owner = T;
|
||||
|
||||
template <typename T>
|
||||
using not_null = T;
|
||||
|
||||
/// \brief perform a narrowing cast without checks
|
||||
///
|
||||
template <typename T, typename O>
|
||||
inline constexpr T narrow_cast(O && v) noexcept
|
||||
{
|
||||
static_assert(plib::is_arithmetic<T>::value && std::is_convertible<std::remove_reference_t<O>, T>::value, "narrow cast expects conversion between arithmetic types");
|
||||
return static_cast<T>(std::forward<O>(v));
|
||||
}
|
||||
|
||||
/// \brief perform a narrowing cast terminating if loss of precision
|
||||
///
|
||||
/// The c++ core guidelines require the narrow function to raise an error
|
||||
/// This will make narrow noexcept(false). This has shown to have a
|
||||
/// measurable impact on performance and thus we deviate we deviate from
|
||||
/// the standard here.
|
||||
///
|
||||
template <typename T, typename O>
|
||||
inline T narrow(O && v) noexcept
|
||||
{
|
||||
static_assert(plib::is_arithmetic<T>::value && std::is_convertible<std::remove_reference_t<O>, T>::value, "narrow cast expects conversion between arithmetic types");
|
||||
|
||||
const auto val = static_cast<T>(std::forward<O>(v));
|
||||
if( v == static_cast<std::remove_reference_t<O>>(val))
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
plib::terminate("narrowing_error");
|
||||
// throw narrowing_error();
|
||||
}
|
||||
|
||||
} // namespace pgsl
|
||||
|
||||
/// \brief downcast from base tpye to derived type
|
||||
///
|
||||
/// The cpp core guidelines require a very careful use of static cast
|
||||
/// for downcast operations. This template is used to identify these uses
|
||||
/// and later for debug builds use dynamic_cast.
|
||||
///
|
||||
template <typename D, typename B>
|
||||
inline constexpr D downcast(B && b) noexcept
|
||||
{
|
||||
static_assert(std::is_pointer<D>::value || std::is_reference<D>::value, "downcast only supports pointers or reference for derived");
|
||||
static_assert(std::is_pointer<B>::value || std::is_reference<B>::value, "downcast only supports pointers or reference for base");
|
||||
return static_cast<D>(std::forward<B>(b));
|
||||
}
|
||||
|
||||
using pgsl::narrow_cast;
|
||||
} // namespace plib
|
||||
|
||||
//FIXME: This is the place to use more complete implementations
|
||||
namespace gsl = plib::pgsl;
|
||||
|
||||
#endif // PGSL_H_
|
@ -62,11 +62,13 @@ namespace plib {
|
||||
|
||||
reference operator[](size_type index) noexcept
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return reinterpret_cast<reference>(m_buf[index]);
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type index) const noexcept
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return reinterpret_cast<const_reference>(m_buf[index]);
|
||||
}
|
||||
|
||||
@ -78,13 +80,19 @@ namespace plib {
|
||||
new (&m_buf[index]) C(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[N]); }
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[N]); }
|
||||
|
||||
protected:
|
||||
|
@ -29,8 +29,8 @@ namespace plib {
|
||||
int app::main_utfX(int argc, char *argv[])
|
||||
{
|
||||
std::vector<putf8string> arg;
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(argc); i++)
|
||||
arg.push_back(putf8string(argv[i]));
|
||||
for (std::size_t i = 0; i < narrow_cast<std::size_t>(argc); i++)
|
||||
arg.emplace_back(putf8string(argv[i]));
|
||||
|
||||
return main_utfX(arg);
|
||||
}
|
||||
@ -38,8 +38,8 @@ namespace plib {
|
||||
int app::main_utfX(int argc, wchar_t *argv[])
|
||||
{
|
||||
std::vector<putf8string> arg;
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(argc); i++)
|
||||
arg.push_back(putf8string(pwstring(argv[i])));
|
||||
for (std::size_t i = 0; i < narrow_cast<std::size_t>(argc); i++)
|
||||
arg.emplace_back(putf8string(pwstring(argv[i])));
|
||||
|
||||
return main_utfX(arg);
|
||||
}
|
||||
|
@ -15,9 +15,7 @@
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#if (PUSE_FLOAT128)
|
||||
#include <quadmath.h>
|
||||
#endif
|
||||
// quadmath.h included by ptypes.h
|
||||
|
||||
namespace plib
|
||||
{
|
||||
|
164
src/lib/netlist/plib/pmatrix2d.h
Normal file → Executable file
164
src/lib/netlist/plib/pmatrix2d.h
Normal file → Executable file
@ -17,51 +17,182 @@
|
||||
namespace plib
|
||||
{
|
||||
|
||||
template<typename T, typename A = aligned_allocator<T>>
|
||||
template<typename T, typename A = aligned_arena>
|
||||
class pmatrix2d
|
||||
{
|
||||
public:
|
||||
using size_type = std::size_t;
|
||||
using value_type = T;
|
||||
using allocator_type = A;
|
||||
using arena_type = A;
|
||||
using allocator_type = typename A::template allocator_type<T>;
|
||||
|
||||
static constexpr const size_type align_size = align_traits<allocator_type>::align_size;
|
||||
static constexpr const size_type stride_size = align_traits<allocator_type>::stride_size;
|
||||
|
||||
using value_type = T;
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
|
||||
static constexpr const size_type align_size = align_traits<A>::align_size;
|
||||
static constexpr const size_type stride_size = align_traits<A>::stride_size;
|
||||
pmatrix2d() noexcept
|
||||
: m_N(0), m_M(0), m_stride(8), m_v()
|
||||
: m_N(0), m_M(0), m_stride(8), m_v(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
pmatrix2d(size_type N, size_type M)
|
||||
: m_N(N), m_M(M), m_v()
|
||||
{
|
||||
gsl_Expects(N>0);
|
||||
gsl_Expects(M>0);
|
||||
m_stride = ((M + stride_size-1) / stride_size) * stride_size;
|
||||
m_v.resize(N * m_stride);
|
||||
m_v = m_a.allocate(N * m_stride);
|
||||
for (std::size_t i = 0; i < N * m_stride; i++)
|
||||
::new(&m_v[i]) T();
|
||||
}
|
||||
|
||||
~pmatrix2d()
|
||||
{
|
||||
if (m_v != nullptr)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_N * m_stride; i++)
|
||||
(&m_v[i])->~T();
|
||||
m_a.deallocate(m_v, m_N * m_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void resize(size_type N, size_type M)
|
||||
{
|
||||
gsl_Expects(N>0);
|
||||
gsl_Expects(M>0);
|
||||
if (m_v != nullptr)
|
||||
{
|
||||
for (std::size_t i = 0; i < N * m_stride; i++)
|
||||
(&m_v[i])->~T();
|
||||
m_a.deallocate(m_v, N * m_stride);
|
||||
}
|
||||
m_N = N;
|
||||
m_M = M;
|
||||
m_stride = ((M + stride_size-1) / stride_size) * stride_size;
|
||||
m_v = m_a.allocate(N * m_stride);
|
||||
for (std::size_t i = 0; i < N * m_stride; i++)
|
||||
::new(&m_v[i]) T();
|
||||
}
|
||||
|
||||
constexpr pointer operator[] (size_type row) noexcept
|
||||
{
|
||||
return &m_v[m_stride * row];
|
||||
}
|
||||
|
||||
constexpr const_pointer operator[] (size_type row) const noexcept
|
||||
{
|
||||
return &m_v[m_stride * row];
|
||||
}
|
||||
|
||||
reference operator()(size_type r, size_type c) noexcept
|
||||
{
|
||||
return (*this)[r][c];
|
||||
}
|
||||
|
||||
const_reference operator()(size_type r, size_type c) const noexcept
|
||||
{
|
||||
return (*this)[r][c];
|
||||
}
|
||||
|
||||
// for compatibility with vrl variant
|
||||
void set(size_type r, size_type c, const value_type &v) noexcept
|
||||
{
|
||||
(*this)[r][c] = v;
|
||||
}
|
||||
|
||||
pointer data() noexcept
|
||||
{
|
||||
return m_v;
|
||||
}
|
||||
|
||||
const_pointer data() const noexcept
|
||||
{
|
||||
return m_v;
|
||||
}
|
||||
|
||||
size_type didx(size_type r, size_type c) const noexcept
|
||||
{
|
||||
return m_stride * r + c;
|
||||
}
|
||||
private:
|
||||
|
||||
size_type m_N;
|
||||
size_type m_M;
|
||||
size_type m_stride;
|
||||
|
||||
T * __restrict m_v;
|
||||
|
||||
allocator_type m_a;
|
||||
};
|
||||
|
||||
// variable row length matrix
|
||||
template<typename T, typename A = aligned_arena>
|
||||
class pmatrix2d_vrl
|
||||
{
|
||||
public:
|
||||
using size_type = std::size_t;
|
||||
using value_type = T;
|
||||
using arena_type = A;
|
||||
using allocator_type = typename A::template allocator_type<T>;
|
||||
|
||||
static constexpr const size_type align_size = align_traits<allocator_type>::align_size;
|
||||
static constexpr const size_type stride_size = align_traits<allocator_type>::stride_size;
|
||||
pmatrix2d_vrl() noexcept
|
||||
: m_N(0), m_M(0), m_v()
|
||||
{
|
||||
}
|
||||
|
||||
pmatrix2d_vrl(size_type N, size_type M)
|
||||
: m_N(N), m_M(M), m_v()
|
||||
{
|
||||
m_row.resize(N + 1, 0);
|
||||
m_v.resize(N); //FIXME
|
||||
}
|
||||
|
||||
void resize(size_type N, size_type M)
|
||||
{
|
||||
m_N = N;
|
||||
m_M = M;
|
||||
m_stride = ((M + stride_size-1) / stride_size) * stride_size;
|
||||
m_v.resize(N * m_stride);
|
||||
m_row.resize(N + 1);
|
||||
for (std::size_t i = 0; i < m_N; i++)
|
||||
m_row[i] = 0;
|
||||
m_v.resize(N); //FIXME
|
||||
}
|
||||
|
||||
constexpr T * operator[] (size_type row) noexcept
|
||||
{
|
||||
return assume_aligned_ptr<T, align_size>(&m_v[m_stride * row]);
|
||||
return &(m_v[m_row[row]]);
|
||||
}
|
||||
|
||||
constexpr const T * operator[] (size_type row) const noexcept
|
||||
{
|
||||
return assume_aligned_ptr<T, align_size>(&m_v[m_stride * row]);
|
||||
return &(m_v[m_row[row]]);
|
||||
}
|
||||
|
||||
//FIXME: no check!
|
||||
T & operator()(size_type r, size_type c) noexcept
|
||||
{
|
||||
return (*this)[r][c];
|
||||
}
|
||||
|
||||
void set(size_type r, size_type c, const T &v) noexcept
|
||||
{
|
||||
if (c + m_row[r] >= m_row[r + 1])
|
||||
{
|
||||
m_v.insert(m_v.begin() + narrow_cast<std::ptrdiff_t>(m_row[r+1]), v);
|
||||
for (size_type i = r + 1; i <= m_N; i++)
|
||||
m_row[i] = m_row[i] + 1;
|
||||
}
|
||||
else
|
||||
(*this)[r][c] = v;
|
||||
}
|
||||
|
||||
//FIXME: no check!
|
||||
const T & operator()(size_type r, size_type c) const noexcept
|
||||
{
|
||||
return (*this)[r][c];
|
||||
@ -77,19 +208,22 @@ namespace plib
|
||||
return m_v.data();
|
||||
}
|
||||
|
||||
//FIXME: no check!
|
||||
size_type didx(size_type r, size_type c) const noexcept
|
||||
{
|
||||
return m_stride * r + c;
|
||||
return m_row[r] + c;
|
||||
}
|
||||
|
||||
std::size_t tx() const { return m_v.size(); }
|
||||
private:
|
||||
|
||||
size_type m_N;
|
||||
size_type m_M;
|
||||
size_type m_stride;
|
||||
|
||||
std::vector<T, A> m_v;
|
||||
std::vector<size_type, typename A::template allocator_type<size_type>> m_row;
|
||||
std::vector<T, allocator_type> m_v;
|
||||
};
|
||||
|
||||
|
||||
} // namespace plib
|
||||
|
||||
#endif // PMATRIX2D_H_
|
||||
|
@ -40,31 +40,26 @@ namespace plib {
|
||||
mempool_arena(size_t min_alloc = (1<<21), size_t min_align = PALIGN_CACHELINE)
|
||||
: m_min_alloc(min_alloc)
|
||||
, m_min_align(min_align)
|
||||
, m_block_align(1024)
|
||||
, m_blocks(base_allocator_type<block *>(m_arena))
|
||||
{
|
||||
icount()++;
|
||||
}
|
||||
|
||||
PCOPYASSIGNMOVE(mempool_arena, delete)
|
||||
|
||||
~mempool_arena()
|
||||
{
|
||||
|
||||
for (auto & b : m_blocks)
|
||||
{
|
||||
if (b->m_num_alloc != 0)
|
||||
{
|
||||
plib::perrlogger("Found {} info blocks\n", sinfo().size());
|
||||
plib::perrlogger("Found {} info blocks\n", m_info.size());
|
||||
plib::perrlogger("Found block with {} dangling allocations\n", b->m_num_alloc);
|
||||
}
|
||||
m_arena.free(b);
|
||||
//::operator delete(b->m_data);
|
||||
}
|
||||
if (icount()-- == 1)
|
||||
{
|
||||
if (!sinfo().empty())
|
||||
plib::perrlogger("Still found {} info blocks after last mempool deleted\n", sinfo().size());
|
||||
detail::free(m_arena, b);
|
||||
}
|
||||
if (!m_info.empty())
|
||||
plib::perrlogger("Still found {} info blocks after mempool deleted\n", m_info.size());
|
||||
}
|
||||
|
||||
void *allocate(size_t align, size_t size)
|
||||
@ -92,21 +87,18 @@ namespace plib {
|
||||
void *ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
|
||||
auto capacity(rs);
|
||||
ret = std::align(align, size, ret, capacity);
|
||||
sinfo().insert({ ret, info(b, b->m_cur)});
|
||||
m_info.insert({ ret, info(b, b->m_cur)});
|
||||
rs -= (capacity - size);
|
||||
b->m_cur += rs;
|
||||
base_type::m_stat_cur_alloc() += size;
|
||||
if (base_type::m_stat_max_alloc() < base_type::m_stat_cur_alloc())
|
||||
base_type::m_stat_max_alloc() = base_type::m_stat_cur_alloc();
|
||||
this->inc_alloc_stat(size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*static */ void deallocate(void *ptr, size_t size) noexcept
|
||||
void deallocate(void *ptr, size_t size) noexcept
|
||||
{
|
||||
|
||||
auto it = sinfo().find(ptr);
|
||||
if (it == sinfo().end())
|
||||
auto it = m_info.find(ptr);
|
||||
if (it == m_info.end())
|
||||
plib::terminate("mempool::free - pointer not found");
|
||||
block *b = it->second.m_block;
|
||||
if (b->m_num_alloc == 0)
|
||||
@ -115,7 +107,7 @@ namespace plib {
|
||||
{
|
||||
mempool_arena &mp = b->m_mempool;
|
||||
b->m_num_alloc--;
|
||||
mp.m_stat_cur_alloc() -= size;
|
||||
mp.dec_alloc_stat(size);
|
||||
if (b->m_num_alloc == 0)
|
||||
{
|
||||
auto itb = std::find(mp.m_blocks.begin(), mp.m_blocks.end(), b);
|
||||
@ -123,14 +115,15 @@ namespace plib {
|
||||
plib::terminate("mempool::free - block not found");
|
||||
|
||||
mp.m_blocks.erase(itb);
|
||||
m_arena.free(b);
|
||||
detail::free(mp.base_arena(), b);
|
||||
}
|
||||
sinfo().erase(it);
|
||||
m_info.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool operator ==(const mempool_arena &rhs) const noexcept { return this == &rhs; }
|
||||
|
||||
BASEARENA &base_arena() noexcept { return m_arena; }
|
||||
private:
|
||||
struct block
|
||||
{
|
||||
@ -142,17 +135,19 @@ namespace plib {
|
||||
{
|
||||
min_bytes = std::max(mp.m_min_alloc, min_bytes);
|
||||
m_free = min_bytes;
|
||||
size_type alloc_bytes = (min_bytes + mp.m_min_align); // - 1); // & ~(mp.m_min_align - 1);
|
||||
m_bytes_allocated = (min_bytes + mp.m_block_align); // - 1); // & ~(mp.m_min_align - 1);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
m_data_allocated = new std::uint8_t[alloc_bytes];
|
||||
//m_data_allocated = new std::uint8_t[alloc_bytes];
|
||||
m_data_allocated = static_cast<std::uint8_t *>(mp.base_arena().allocate(mp.m_block_align, m_bytes_allocated));
|
||||
void *r = m_data_allocated;
|
||||
std::align(mp.m_min_align, min_bytes, r, alloc_bytes);
|
||||
std::align(mp.m_block_align, min_bytes, r, m_bytes_allocated);
|
||||
m_data = reinterpret_cast<std::uint8_t *>(r);
|
||||
}
|
||||
~block()
|
||||
{
|
||||
//::operator delete(m_data_allocated);
|
||||
delete [] m_data_allocated;
|
||||
//delete [] m_data_allocated;
|
||||
m_mempool.base_arena().deallocate(m_data_allocated, m_bytes_allocated);
|
||||
}
|
||||
|
||||
block(const block &) = delete;
|
||||
@ -163,6 +158,7 @@ namespace plib {
|
||||
size_type m_num_alloc;
|
||||
size_type m_free;
|
||||
size_type m_cur;
|
||||
size_type m_bytes_allocated;
|
||||
std::uint8_t *m_data;
|
||||
std::uint8_t *m_data_allocated;
|
||||
mempool_arena &m_mempool;
|
||||
@ -180,27 +176,20 @@ namespace plib {
|
||||
|
||||
block * new_block(size_type min_bytes)
|
||||
{
|
||||
auto *b = m_arena.template alloc<block>(*this, min_bytes);
|
||||
auto *b = detail::alloc<block>(m_arena, *this, min_bytes);
|
||||
m_blocks.push_back(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
static std::unordered_map<void *, info> &sinfo()
|
||||
{
|
||||
static std::unordered_map<void *, info> spinfo;
|
||||
return spinfo;
|
||||
}
|
||||
|
||||
static std::size_t &icount()
|
||||
{
|
||||
static std::size_t count = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t m_min_alloc;
|
||||
size_t m_min_align;
|
||||
size_t m_block_align;
|
||||
BASEARENA m_arena;
|
||||
|
||||
using base_allocator_typex = typename BASEARENA::template allocator_type<std::pair<void * const, info>>;
|
||||
std::unordered_map<void *, info, std::hash<void *>, std::equal_to<void *>,
|
||||
base_allocator_typex> m_info;
|
||||
// std::unordered_map<void *, info> m_info;
|
||||
std::vector<block *, typename BASEARENA::template allocator_type<block *>> m_blocks;
|
||||
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ namespace plib {
|
||||
auto *o = dynamic_cast<option *>(opt);
|
||||
if (o != nullptr)
|
||||
{
|
||||
if (o->short_opt() == "" && o->long_opt() == "")
|
||||
if (o->short_opt().empty() && o->long_opt().empty())
|
||||
{
|
||||
auto *ov = dynamic_cast<option_args *>(o);
|
||||
if (ov != nullptr)
|
||||
@ -103,7 +103,7 @@ namespace plib {
|
||||
if (!seen_other_args && plib::startsWith(arg, "--"))
|
||||
{
|
||||
auto v = psplit(arg.substr(2),"=");
|
||||
if (!v.empty() && v[0] != "")
|
||||
if (!v.empty() && !v[0].empty())
|
||||
{
|
||||
opt = getopt_long(v[0]);
|
||||
has_equal_arg = (v.size() > 1);
|
||||
@ -210,11 +210,11 @@ namespace plib {
|
||||
if (auto * const opt = dynamic_cast<option *>(optbase))
|
||||
{
|
||||
pstring line = "";
|
||||
if (opt->short_opt() != "")
|
||||
if (!opt->short_opt().empty())
|
||||
line += " -" + opt->short_opt();
|
||||
if (opt->long_opt() != "")
|
||||
if (!opt->long_opt().empty())
|
||||
{
|
||||
if (line != "")
|
||||
if (!line.empty())
|
||||
line += ", ";
|
||||
else
|
||||
line = " ";
|
||||
@ -248,7 +248,8 @@ namespace plib {
|
||||
else if (auto *grp = dynamic_cast<option_group *>(optbase))
|
||||
{
|
||||
ret += "\n" + grp->group() + ":\n";
|
||||
if (grp->help() != "") ret += split_paragraphs(grp->help(), width, 4, 4) + "\n\n";
|
||||
if (!grp->help().empty())
|
||||
ret += split_paragraphs(grp->help(), width, 4, 4) + "\n\n";
|
||||
}
|
||||
}
|
||||
// FIXME: other help ...
|
||||
@ -274,7 +275,7 @@ namespace plib {
|
||||
for (const auto & optbase : m_opts)
|
||||
{
|
||||
auto *opt = dynamic_cast<option *>(optbase);
|
||||
if (opt != nullptr && arg != "" && opt->short_opt() == arg)
|
||||
if (opt != nullptr && !arg.empty() && opt->short_opt() == arg)
|
||||
return opt;
|
||||
}
|
||||
return nullptr;
|
||||
@ -284,7 +285,7 @@ namespace plib {
|
||||
for (const auto & optbase : m_opts)
|
||||
{
|
||||
auto *opt = dynamic_cast<option *>(optbase);
|
||||
if (opt != nullptr && arg !="" && opt->long_opt() == arg)
|
||||
if (opt != nullptr && !arg.empty() && opt->long_opt() == arg)
|
||||
return opt;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -136,7 +136,7 @@ namespace plib {
|
||||
|
||||
if (raw != plib::container::npos)
|
||||
{
|
||||
m_val = static_cast<T>(raw);
|
||||
m_val = narrow_cast<T>(raw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,32 +159,43 @@ namespace plib {
|
||||
if (PMFINTERNAL == 1)
|
||||
{
|
||||
// apply the "this" delta to the object first
|
||||
// NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
|
||||
// NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult,cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
generic_class *o_p_delta = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
|
||||
|
||||
// if the low bit of the vtable index is clear, then it is just a raw function pointer
|
||||
if ((m_function & 1) == 0)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
func = reinterpret_cast<generic_function>(m_function);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, it is the byte index into the vtable where the actual function lives
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(o_p_delta);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
func = *reinterpret_cast<generic_function *>(vtable_base + m_function - 1);
|
||||
}
|
||||
object = o_p_delta;
|
||||
}
|
||||
else if (PMFINTERNAL == 2)
|
||||
{
|
||||
if ((m_this_delta & 1) == 0) {
|
||||
if ((m_this_delta & 1) == 0)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
object = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
func = reinterpret_cast<generic_function>(m_function);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
object = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object));
|
||||
|
||||
// otherwise, it is the byte index into the vtable where the actual function lives
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(object);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
func = *reinterpret_cast<generic_function *>(vtable_base + m_function + m_this_delta - 1);
|
||||
}
|
||||
}
|
||||
@ -192,8 +203,10 @@ namespace plib {
|
||||
{
|
||||
const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (generic_class::*)());
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
func = reinterpret_cast<generic_function>(m_function);
|
||||
if (m_size == SINGLE_MEMFUNCPTR_SIZE + sizeof(int))
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
object = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
|
||||
}
|
||||
}
|
||||
@ -231,8 +244,10 @@ namespace plib {
|
||||
{
|
||||
raw_type mfpo(mftp);
|
||||
generic_function_storage rfunc(nullptr);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto *robject = reinterpret_cast<generic_class *>(object);
|
||||
mfpo.convert_to_generic(rfunc, robject);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return std::make_pair(reinterpret_cast<FunctionType>(rfunc), reinterpret_cast<ObjectType *>(robject));
|
||||
}
|
||||
template<typename O>
|
||||
@ -259,6 +274,7 @@ namespace plib {
|
||||
template<typename FunctionType, typename MemberFunctionType, typename ObjectType>
|
||||
static std::pair<FunctionType, ObjectType *> get(MemberFunctionType mftp, ObjectType *object)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return std::make_pair(reinterpret_cast<FunctionType>(mftp), reinterpret_cast<ObjectType *>(object));
|
||||
}
|
||||
|
||||
@ -286,6 +302,7 @@ namespace plib {
|
||||
template<typename FunctionType, typename MemberFunctionType, typename ObjectType>
|
||||
static std::pair<FunctionType, ObjectType *> get(MemberFunctionType mftp, ObjectType *object)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return std::make_pair(reinterpret_cast<FunctionType>(object->*mftp), reinterpret_cast<ObjectType *>(object));
|
||||
}
|
||||
template<typename O>
|
||||
@ -315,6 +332,7 @@ namespace plib {
|
||||
pmfp_base()
|
||||
: m_obj(nullptr)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
|
||||
std::fill(s, s + sizeof(m_resolved), 0);
|
||||
}
|
||||
@ -323,6 +341,7 @@ namespace plib {
|
||||
pmfp_base(specific_member_function<O> mftp, O *object)
|
||||
: m_obj(nullptr)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
|
||||
std::fill(s, s + sizeof(m_resolved), 0);
|
||||
bind(object, &mftp);
|
||||
@ -351,6 +370,7 @@ namespace plib {
|
||||
//auto pFunc = *reinterpret_cast<specific_member_function<O> *>(fraw); // mftp;
|
||||
specific_member_function<O> pFunc;
|
||||
static_assert(sizeof(pFunc) >= sizeof(MF), "size error");
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
*reinterpret_cast<MF *>(&pFunc) = *fraw;
|
||||
|
||||
auto r = helper::template get<member_abi_function<O>>(pFunc, object);
|
||||
@ -360,18 +380,21 @@ namespace plib {
|
||||
|
||||
//*reinterpret_cast<member_abi_function<O> *>(&m_resolved) = r.first;
|
||||
reinterpret_copy(r.first, m_resolved);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
m_obj = reinterpret_cast<generic_class *>(r.second);
|
||||
}
|
||||
|
||||
template<typename O>
|
||||
R call(O *obj, Targs&&... args) const noexcept(true)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return helper::call(reinterpret_cast<member_abi_function<O> *>(&m_resolved),
|
||||
obj, std::forward<Targs>(args)...);
|
||||
}
|
||||
|
||||
R call(Targs&&... args) const noexcept(true)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return helper::call(reinterpret_cast<const member_abi_function<generic_class> *>(&m_resolved),
|
||||
m_obj, std::forward<Targs>(args)...);
|
||||
}
|
||||
@ -414,12 +437,13 @@ namespace plib {
|
||||
|
||||
using static_creator = return_type (*)(const generic_member_function *, generic_class *);
|
||||
|
||||
late_pmfp() {}
|
||||
late_pmfp() = default;
|
||||
|
||||
template<typename O>
|
||||
late_pmfp(specific_member_function<O> mftp)
|
||||
{
|
||||
static_assert(sizeof(m_raw) >= sizeof(specific_member_function<O>), "size issue");
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
*reinterpret_cast<specific_member_function<O> *>(&m_raw) = mftp;
|
||||
m_creator = creator<O>;
|
||||
}
|
||||
@ -427,6 +451,7 @@ namespace plib {
|
||||
template<typename O>
|
||||
return_type operator()(O *object) const
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return m_creator(&m_raw, reinterpret_cast<generic_class *>(object));
|
||||
}
|
||||
|
||||
@ -435,7 +460,9 @@ namespace plib {
|
||||
template <typename O>
|
||||
static return_type creator(const generic_member_function *raw, generic_class *obj)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto p = reinterpret_cast<const specific_member_function<O> *>(raw);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto o = reinterpret_cast<O *>(obj);
|
||||
return return_type(*p, o);
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ namespace plib {
|
||||
m_if_level++;
|
||||
lt = replace_macros(lt);
|
||||
simple_iter<ppreprocessor> t(this, tokenize(lt.substr(3), m_expr_sep, true, true));
|
||||
auto val = static_cast<int>(prepro_expr(t, 255));
|
||||
auto val = narrow_cast<int>(prepro_expr(t, 255));
|
||||
t.skip_ws();
|
||||
if (!t.eod())
|
||||
error("found unprocessed content at end of line");
|
||||
@ -489,7 +489,7 @@ namespace plib {
|
||||
m_if_flag ^= (1 << m_if_level);
|
||||
lt = replace_macros(lt);
|
||||
simple_iter<ppreprocessor> t(this, tokenize(lt.substr(5), m_expr_sep, true, true));
|
||||
auto val = static_cast<int>(prepro_expr(t, 255));
|
||||
auto val = narrow_cast<int>(prepro_expr(t, 255));
|
||||
t.skip_ws();
|
||||
if (!t.eod())
|
||||
error("found unprocessed content at end of line");
|
||||
@ -559,7 +559,7 @@ namespace plib {
|
||||
auto *prevdef = get_define(n);
|
||||
if (lti.size() == 2)
|
||||
{
|
||||
if (prevdef != nullptr && prevdef->m_replace != "")
|
||||
if (prevdef != nullptr && !prevdef->m_replace.empty())
|
||||
error("redefinition of " + n);
|
||||
m_defines.insert({n, define_t(n, "")});
|
||||
}
|
||||
|
@ -95,14 +95,14 @@ namespace plib {
|
||||
if (this->gptr() == this->egptr())
|
||||
{
|
||||
// clang reports sign error - weird
|
||||
std::size_t bytes = m_strm->m_outbuf.size() - static_cast<std::size_t>(m_strm->m_pos);
|
||||
std::size_t bytes = m_strm->m_outbuf.size() - narrow_cast<std::size_t>(m_strm->m_pos);
|
||||
|
||||
if (bytes > m_buf.size())
|
||||
bytes = m_buf.size();
|
||||
std::copy(m_strm->m_outbuf.c_str() + m_strm->m_pos, m_strm->m_outbuf.c_str() + m_strm->m_pos + bytes, m_buf.data());
|
||||
this->setg(m_buf.data(), m_buf.data(), m_buf.data() + bytes);
|
||||
|
||||
m_strm->m_pos += static_cast<long>(bytes);
|
||||
m_strm->m_pos += narrow_cast<long>(bytes);
|
||||
}
|
||||
|
||||
return this->gptr() == this->egptr()
|
||||
|
@ -9,6 +9,7 @@
|
||||
///
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pgsl.h"
|
||||
#include "pmath.h"
|
||||
#include "ptypes.h"
|
||||
|
||||
@ -50,7 +51,7 @@ namespace plib
|
||||
seed(5489);
|
||||
}
|
||||
|
||||
static constexpr T min() noexcept { return static_cast<T>(0); }
|
||||
static constexpr T min() noexcept { return T(0); }
|
||||
static constexpr T max() noexcept { return ~T(0) >> (sizeof(T)*8 - w); }
|
||||
|
||||
template <typename ST>
|
||||
@ -103,7 +104,7 @@ namespace plib
|
||||
void twist()
|
||||
{
|
||||
const T lowest_w(~T(0) >> (sizeof(T)*8 - w));
|
||||
const T lower_mask((static_cast<T>(1) << r) - 1); // That is, the binary number of r 1's
|
||||
const T lower_mask((T(1) << r) - 1); // That is, the binary number of r 1's
|
||||
const T upper_mask((~lower_mask) & lowest_w);
|
||||
|
||||
for (std::size_t i=0; i<N; i++)
|
||||
@ -122,10 +123,10 @@ namespace plib
|
||||
template <typename FT, typename T>
|
||||
FT normalize_uniform(T &p, FT m = constants<FT>::one(), FT b = constants<FT>::zero())
|
||||
{
|
||||
const auto mmin(static_cast<FT>(p.min()));
|
||||
const auto mmax(static_cast<FT>(p.max()));
|
||||
const auto mmin(narrow_cast<FT>(p.min()));
|
||||
const auto mmax(narrow_cast<FT>(p.max()));
|
||||
// -> 0 to a
|
||||
return (static_cast<FT>(p())- mmin) / (mmax - mmin) * m - b;
|
||||
return (narrow_cast<FT>(p())- mmin) / (mmax - mmin) * m - b;
|
||||
}
|
||||
|
||||
template<typename FT>
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pexception.h"
|
||||
#include "pgsl.h"
|
||||
#include "pmath.h" // for pstonum
|
||||
#include "pstring.h"
|
||||
|
||||
@ -36,9 +37,9 @@ namespace plib
|
||||
if (ss >> x)
|
||||
{
|
||||
auto pos(ss.tellg());
|
||||
if (pos == static_cast<decltype(pos)>(-1))
|
||||
if (pos == decltype(pos)(-1))
|
||||
pos = len;
|
||||
*idx = static_cast<std::size_t>(pos);
|
||||
*idx = narrow_cast<std::size_t>(pos);
|
||||
}
|
||||
else
|
||||
*idx = constants<std::size_t>::zero();
|
||||
@ -88,7 +89,7 @@ namespace plib
|
||||
template <typename S>
|
||||
FLOAT128 operator()(std::locale loc, const S &arg, std::size_t *idx)
|
||||
{
|
||||
return static_cast<FLOAT128>(pstonum_locale<long double>(loc, arg, idx));
|
||||
return narrow_cast<FLOAT128>(pstonum_locale<long double>(loc, arg, idx));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@ -100,8 +101,8 @@ namespace plib
|
||||
std::size_t idx(0);
|
||||
auto ret = pstonum_helper<T>()(loc, cstr, &idx);
|
||||
using ret_type = decltype(ret);
|
||||
if (ret >= static_cast<ret_type>(plib::numeric_limits<T>::lowest())
|
||||
&& ret <= static_cast<ret_type>(plib::numeric_limits<T>::max()))
|
||||
if (ret >= narrow_cast<ret_type>(plib::numeric_limits<T>::lowest())
|
||||
&& ret <= narrow_cast<ret_type>(plib::numeric_limits<T>::max()))
|
||||
{
|
||||
if (cstr[idx] != 0)
|
||||
throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr));
|
||||
@ -110,7 +111,7 @@ namespace plib
|
||||
{
|
||||
throw pexception(pstring("Out of range: ") + pstring(cstr));
|
||||
}
|
||||
return static_cast<T>(ret);
|
||||
return narrow_cast<T>(ret);
|
||||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@ -204,7 +204,7 @@ public:
|
||||
{
|
||||
const auto sz(static_cast<std::streamsize>(val.size()));
|
||||
write(sz);
|
||||
m_strm.write(reinterpret_cast<const std::ostream::char_type *>(val.data()), sz * static_cast<std::streamsize>(sizeof(T)));
|
||||
m_strm.write(reinterpret_cast<const std::ostream::char_type *>(val.data()), sz * gsl::narrow<std::streamsize>(sizeof(T)));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -225,7 +225,7 @@ public:
|
||||
template <typename T>
|
||||
void read(T &val)
|
||||
{
|
||||
m_strm.read(reinterpret_cast<std::istream::char_type *>(&val), sizeof(T));
|
||||
m_strm.read(reinterpret_cast<std::istream::char_type *>(&val), gsl::narrow<std::streamsize>(sizeof(T)));
|
||||
}
|
||||
|
||||
void read( pstring &s)
|
||||
@ -244,7 +244,7 @@ public:
|
||||
std::size_t sz = 0;
|
||||
read(sz);
|
||||
val.resize(sz);
|
||||
m_strm.read(reinterpret_cast<std::istream::char_type *>(val.data()), static_cast<std::streamsize>(sizeof(T) * sz));
|
||||
m_strm.read(reinterpret_cast<std::istream::char_type *>(val.data()), gsl::narrow<std::streamsize>(sizeof(T) * sz));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -289,7 +289,7 @@ public:
|
||||
pstring_t<pwchar_traits>, pstring_t<putf8_traits>>::type;
|
||||
|
||||
template <typename T>
|
||||
explicit ofstream(const pstring_t<T> name, ios_base::openmode mode = ios_base::in)
|
||||
explicit ofstream(const pstring_t<T> name, ios_base::openmode mode = ios_base::out | ios_base::trunc)
|
||||
: std::ofstream(filename_type(name).c_str(), mode)
|
||||
{
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ int pstring_t<F>::compare(const pstring_t &right) const noexcept
|
||||
}
|
||||
|
||||
if (si != this->end() && ri != right.end())
|
||||
return static_cast<int>(*si) - static_cast<int>(*ri);
|
||||
return plib::narrow_cast<int>(*si) - plib::narrow_cast<int>(*ri);
|
||||
if (this->mem_t_size() > right.mem_t_size())
|
||||
return 1;
|
||||
if (this->mem_t_size() < right.mem_t_size())
|
||||
@ -45,8 +45,8 @@ pstring_t<F> pstring_t<F>::substr(size_type start, size_type nlen) const
|
||||
{
|
||||
if (nlen == npos || start + nlen > l)
|
||||
nlen = l - start;
|
||||
auto ps = std::next(begin(), static_cast<difference_type>(start));
|
||||
auto pe = std::next(ps, static_cast<difference_type>(nlen));
|
||||
auto ps = std::next(begin(), plib::narrow_cast<difference_type>(start));
|
||||
auto pe = std::next(ps, plib::narrow_cast<difference_type>(nlen));
|
||||
ret.m_str.assign(ps.p, pe.p);
|
||||
}
|
||||
return ret;
|
||||
|
@ -8,6 +8,7 @@
|
||||
/// \file pstrutil.h
|
||||
///
|
||||
|
||||
#include "pgsl.h"
|
||||
#include "pstring.h"
|
||||
#include "ptypes.h"
|
||||
|
||||
@ -157,13 +158,13 @@ namespace plib
|
||||
template<typename T, typename TA>
|
||||
bool startsWith(const T &str, const TA &arg)
|
||||
{
|
||||
return startsWith(str, static_cast<pstring>(arg));
|
||||
return startsWith(str, static_cast<T>(arg));
|
||||
}
|
||||
|
||||
template<typename T, typename TA>
|
||||
bool endsWith(const T &str, const TA &arg)
|
||||
{
|
||||
return endsWith(str, static_cast<pstring>(arg));
|
||||
return endsWith(str, static_cast<T>(arg));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -172,7 +173,7 @@ namespace plib
|
||||
const T *p = str;
|
||||
while (*p != 0)
|
||||
p++;
|
||||
return static_cast<std::size_t>(p - str);
|
||||
return narrow_cast<std::size_t>(p - str);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -210,7 +210,7 @@ namespace plib {
|
||||
// save state support & mame disasm
|
||||
|
||||
const T *listptr() const noexcept { return &m_list[1]; }
|
||||
std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); }
|
||||
std::size_t size() const noexcept { return narrow_cast<std::size_t>(m_end - &m_list[1]); }
|
||||
const T & operator[](std::size_t index) const noexcept { return m_list[ 1 + index]; }
|
||||
private:
|
||||
using mutex_type = pspin_mutex<TS>;
|
||||
|
@ -15,8 +15,12 @@
|
||||
#include <type_traits>
|
||||
|
||||
#if (PUSE_FLOAT128)
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<quadmath.h>)
|
||||
#include <quadmath.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// noexcept on move operator -> issue with macosx clang
|
||||
#define PCOPYASSIGNMOVE(name, def) \
|
||||
@ -273,7 +277,7 @@ namespace plib
|
||||
template <typename T> class name \
|
||||
{ \
|
||||
template <typename U> static long test(decltype(&U:: member)); \
|
||||
template <typename U> static char test(...); \
|
||||
template <typename U> static char test(...); \
|
||||
public: \
|
||||
static constexpr const bool value = sizeof(test<T>(nullptr)) == sizeof(long); \
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include "putil.h"
|
||||
#include "penum.h"
|
||||
#include "pstream.h"
|
||||
#include "pstrutil.h"
|
||||
#include "ptypes.h"
|
||||
#include "pstream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib> // needed for getenv ...
|
||||
@ -22,7 +22,7 @@ namespace plib
|
||||
{
|
||||
auto p=find_last_of(filename, pstring(PATH_SEPS));
|
||||
pstring ret = (p == pstring::npos) ? filename : filename.substr(p+1);
|
||||
if (suffix != "" && endsWith(ret, suffix))
|
||||
if (!suffix.empty() && endsWith(ret, suffix))
|
||||
return ret.substr(0, ret.length() - suffix.length());
|
||||
return ret;
|
||||
}
|
||||
@ -49,7 +49,7 @@ namespace plib
|
||||
pstring ret = "";
|
||||
for( const auto &elem : list )
|
||||
{
|
||||
if (ret == "")
|
||||
if (ret.empty())
|
||||
ret = elem;
|
||||
else
|
||||
ret += (PATH_SEP + elem);
|
||||
@ -126,7 +126,7 @@ namespace plib
|
||||
auto i = str.begin();
|
||||
while (i != str.end())
|
||||
{
|
||||
auto p = static_cast<std::size_t>(-1);
|
||||
auto p = pstring::npos;
|
||||
for (std::size_t j=0; j < onstrl.size(); j++)
|
||||
{
|
||||
if (std::equal(onstrl[j].begin(), onstrl[j].end(), i))
|
||||
@ -135,14 +135,14 @@ namespace plib
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p != static_cast<std::size_t>(-1))
|
||||
if (p != pstring::npos)
|
||||
{
|
||||
if (col != "")
|
||||
if (!col.empty())
|
||||
ret.push_back(col);
|
||||
|
||||
col = "";
|
||||
ret.push_back(onstrl[p]);
|
||||
i = std::next(i, static_cast<pstring::difference_type>(onstrl[p].length()));
|
||||
i = std::next(i, narrow_cast<pstring::difference_type>(onstrl[p].length()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -151,7 +151,7 @@ namespace plib
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (col != "")
|
||||
if (!col.empty())
|
||||
ret.push_back(col);
|
||||
|
||||
return ret;
|
||||
@ -170,8 +170,8 @@ namespace plib
|
||||
return -1;
|
||||
}
|
||||
|
||||
pstring penum_base::nthstr(int n, const pstring &str)
|
||||
pstring penum_base::nthstr(std::size_t n, const pstring &str)
|
||||
{
|
||||
return psplit(str, ",", false)[static_cast<std::size_t>(n)];
|
||||
return psplit(str, ",", false)[n];
|
||||
}
|
||||
} // namespace plib
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#define PSTRINGIFY_HELP(y) # y
|
||||
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
|
||||
@ -262,7 +262,9 @@ namespace plib
|
||||
void reinterpret_copy(S &s, D &d)
|
||||
{
|
||||
static_assert(sizeof(D) >= sizeof(S), "size mismatch");
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto *dp = reinterpret_cast<std::uint8_t *>(&d);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
const auto *sp = reinterpret_cast<std::uint8_t *>(&s);
|
||||
std::copy(sp, sp + sizeof(S), dp);
|
||||
}
|
||||
@ -290,14 +292,14 @@ namespace plib
|
||||
{
|
||||
auto it = std::find(con.begin(), con.end(), elem);
|
||||
if (it != con.end())
|
||||
return static_cast<std::size_t>(it - con.begin());
|
||||
return narrow_cast<std::size_t>(it - con.begin());
|
||||
return npos;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void insert_at(C &con, const std::size_t index, const typename C::value_type &elem)
|
||||
{
|
||||
con.insert(con.begin() + static_cast<std::ptrdiff_t>(index), elem);
|
||||
con.insert(con.begin() + narrow_cast<std::ptrdiff_t>(index), elem);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
@ -336,7 +338,7 @@ namespace plib
|
||||
{
|
||||
std::size_t result = 5381; // NOLINT
|
||||
for (const T* p = buf; p != buf + size; p++)
|
||||
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<std::size_t>(*p); // NOLINT
|
||||
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ narrow_cast<std::size_t>(*p); // NOLINT
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ public:
|
||||
return stream_ptr(nullptr);
|
||||
|
||||
strm->imbue(std::locale::classic());
|
||||
return std::move(strm); // FIXME: for c++11 clang builds;
|
||||
return strm;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -225,14 +225,14 @@ public:
|
||||
netlist::host_arena::unique_ptr<plib::dynlib_base> static_solver_lib() const override
|
||||
{
|
||||
if (m_boostlib == "builtin")
|
||||
return netlist::host_arena::make_unique<plib::dynlib_static>(nl_static_solver_syms);
|
||||
return plib::make_unique<plib::dynlib_static, netlist::host_arena>(nl_static_solver_syms);
|
||||
if (m_boostlib == "generic")
|
||||
return netlist::host_arena::make_unique<plib::dynlib_static>(nullptr);
|
||||
return plib::make_unique<plib::dynlib_static, netlist::host_arena>(nullptr);
|
||||
if (NL_DISABLE_DYNAMIC_LOAD)
|
||||
throw netlist::nl_exception("Dynamic library loading not supported due to project security concerns.");
|
||||
|
||||
//pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
|
||||
return netlist::host_arena::make_unique<plib::dynlib>(m_boostlib);
|
||||
return plib::make_unique<plib::dynlib, netlist::host_arena>(m_boostlib);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -245,7 +245,7 @@ class netlist_tool_t : public netlist::netlist_state_t
|
||||
public:
|
||||
|
||||
netlist_tool_t(tool_app_t &app, const pstring &name, const pstring &boostlib)
|
||||
: netlist::netlist_state_t(name, netlist::host_arena::make_unique<netlist_tool_callbacks_t>(app, boostlib))
|
||||
: netlist::netlist_state_t(name, plib::make_unique<netlist_tool_callbacks_t, netlist::host_arena>(app, boostlib))
|
||||
{
|
||||
}
|
||||
|
||||
@ -364,13 +364,13 @@ struct input_t
|
||||
case netlist::param_t::POINTER:
|
||||
throw netlist::nl_exception(plib::pfmt("param {1} is not numeric\n")(m_param.param().name()));
|
||||
case netlist::param_t::DOUBLE:
|
||||
static_cast<netlist::param_fp_t*>(&m_param.param())->set(m_value);
|
||||
plib::downcast<netlist::param_fp_t &>(m_param.param()).set(m_value);
|
||||
break;
|
||||
case netlist::param_t::INTEGER:
|
||||
static_cast<netlist::param_int_t*>(&m_param.param())->set(static_cast<int>(m_value));
|
||||
plib::downcast<netlist::param_int_t &>(m_param.param()).set(static_cast<int>(m_value));
|
||||
break;
|
||||
case netlist::param_t::LOGIC:
|
||||
static_cast<netlist::param_logic_t*>(&m_param.param())->set(static_cast<bool>(m_value));
|
||||
plib::downcast<netlist::param_logic_t &>(m_param.param()).set(static_cast<bool>(m_value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -383,7 +383,7 @@ struct input_t
|
||||
static std::vector<input_t> read_input(const netlist::setup_t &setup, const pstring &fname)
|
||||
{
|
||||
std::vector<input_t> ret;
|
||||
if (fname != "")
|
||||
if (!fname.empty())
|
||||
{
|
||||
plib::putf8_reader r = plib::putf8_reader(std::make_unique<plib::ifstream>(plib::filesystem::u8path(fname)));
|
||||
if (r.stream().fail())
|
||||
@ -392,7 +392,7 @@ static std::vector<input_t> read_input(const netlist::setup_t &setup, const pstr
|
||||
pstring l;
|
||||
while (r.readline(l))
|
||||
{
|
||||
if (l != "")
|
||||
if (!l.empty())
|
||||
{
|
||||
input_t inp(setup, l);
|
||||
ret.push_back(inp);
|
||||
@ -659,6 +659,8 @@ void tool_app_t::static_compile()
|
||||
}
|
||||
}
|
||||
plib::ofstream sout(opt_out());
|
||||
if (sout.fail())
|
||||
throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_out()));
|
||||
|
||||
sout << "#include \"plib/pdynlib.h\"\n\n";
|
||||
for (auto &e : map)
|
||||
@ -666,6 +668,7 @@ void tool_app_t::static_compile()
|
||||
sout << "// " << e.second.m_module << "\n";
|
||||
sout << e.second.m_code;
|
||||
}
|
||||
sout << "extern plib::dynlib_static_sym nl_static_solver_syms[];\n";
|
||||
sout << "plib::dynlib_static_sym nl_static_solver_syms[] = {\n";
|
||||
for (auto &e : map)
|
||||
{
|
||||
@ -721,7 +724,7 @@ static doc_ext read_docsrc(const pstring &fname, const pstring &id)
|
||||
if (plib::startsWith(l, "//-"))
|
||||
{
|
||||
l = plib::trim(l.substr(3));
|
||||
if (l != "")
|
||||
if (!l.empty())
|
||||
{
|
||||
auto a(plib::psplit(l, ":", true));
|
||||
if (a.empty() || (a.size() > 2))
|
||||
@ -761,7 +764,7 @@ static doc_ext read_docsrc(const pstring &fname, const pstring &id)
|
||||
else if (n == "FunctionTable")
|
||||
ret.functiontable = v;
|
||||
else if (n == "Param")
|
||||
ret.params.push_back(std::pair<pstring, pstring>(v2, plib::trim(v.substr(v2.length()))));
|
||||
ret.params.emplace_back(v2, plib::trim(v.substr(v2.length())));
|
||||
else if (n == "Example")
|
||||
{
|
||||
ret.example = plib::psplit(plib::trim(v),",",true);
|
||||
@ -818,7 +821,7 @@ void tool_app_t::header_entry(const netlist::factory::element_t *e)
|
||||
avs += ", " + s.substr(1);
|
||||
|
||||
mac_out("// usage : " + e->name() + "(name" + vs + ")", false);
|
||||
if (avs != "")
|
||||
if (!avs.empty())
|
||||
mac_out("// auto connect: " + avs.substr(2), false);
|
||||
|
||||
mac_out("#define " + e->name() + "(...)");
|
||||
@ -942,7 +945,7 @@ void tool_app_t::create_docheader()
|
||||
{
|
||||
auto d(read_docsrc(e->source().file_name(), e->name()));
|
||||
|
||||
if (d.id != "")
|
||||
if (!d.id.empty())
|
||||
{
|
||||
pout("//! [{1} csynopsis]\n", e->name());
|
||||
header_entry(e.get());
|
||||
@ -964,7 +967,7 @@ void tool_app_t::create_docheader()
|
||||
{
|
||||
//auto d(read_docsrc(e->source().file_name(), e->name()));
|
||||
|
||||
if (d.id != "")
|
||||
if (!d.id.empty())
|
||||
{
|
||||
|
||||
poutprefix("///", "");
|
||||
@ -1017,7 +1020,7 @@ void tool_app_t::create_docheader()
|
||||
poutprefix("///", "");
|
||||
poutprefix("///", " @section {}_4 Function Table", d.id);
|
||||
poutprefix("///", "");
|
||||
if (d.functiontable == "")
|
||||
if (!d.functiontable.empty())
|
||||
poutprefix("///", " Please refer to the datasheet.");
|
||||
else
|
||||
poutprefix("///", " {}", d.functiontable);
|
||||
|
@ -655,10 +655,10 @@ void nlwav_app::convert_wav(std::ostream &ostrm, wav_t::format fmt)
|
||||
double dt = plib::reciprocal(static_cast<double>(opt_rate()));
|
||||
auto nchan = m_instrms.size();
|
||||
|
||||
auto wo = arena::make_unique<wavwriter>(ostrm, opt_out() != "-", fmt, nchan, opt_rate(), opt_amp());
|
||||
auto ago = arena::make_unique<aggregator>(nchan, dt, aggregator::callback_type(&wavwriter::process, wo.get()));
|
||||
auto fgo_hp = arena::make_unique<filter_hp>(opt_highpass(), opt_hpboost(), nchan, filter_hp::callback_type(&aggregator::process, ago.get()));
|
||||
auto fgo_lp = arena::make_unique<filter_lp>(opt_lowpass(), nchan, filter_lp::callback_type(&filter_hp::process, fgo_hp.get()));
|
||||
auto wo = plib::make_unique<wavwriter, arena>(ostrm, opt_out() != "-", fmt, nchan, opt_rate(), opt_amp());
|
||||
auto ago = plib::make_unique<aggregator, arena>(nchan, dt, aggregator::callback_type(&wavwriter::process, wo.get()));
|
||||
auto fgo_hp = plib::make_unique<filter_hp, arena>(opt_highpass(), opt_hpboost(), nchan, filter_hp::callback_type(&aggregator::process, ago.get()));
|
||||
auto fgo_lp = plib::make_unique<filter_lp, arena>(opt_lowpass(), nchan, filter_lp::callback_type(&filter_hp::process, fgo_hp.get()));
|
||||
|
||||
auto topcb = log_processor::callback_type(&filter_lp::process, fgo_lp.get());
|
||||
|
||||
@ -680,7 +680,7 @@ void nlwav_app::convert_wav(std::ostream &ostrm, wav_t::format fmt)
|
||||
void nlwav_app::convert_vcd(std::ostream &ostrm, vcdwriter::format_e format)
|
||||
{
|
||||
|
||||
arena::unique_ptr<vcdwriter> wo = arena::make_unique<vcdwriter>(ostrm, opt_args(),
|
||||
arena::unique_ptr<vcdwriter> wo = plib::make_unique<vcdwriter, arena>(ostrm, opt_args(),
|
||||
format, opt_high(), opt_low());
|
||||
log_processor::callback_type agcb = log_processor::callback_type(&vcdwriter::process, wo.get());
|
||||
|
||||
@ -702,7 +702,7 @@ void nlwav_app::convert_vcd(std::ostream &ostrm, vcdwriter::format_e format)
|
||||
void nlwav_app::convert_tab(std::ostream &ostrm)
|
||||
{
|
||||
|
||||
auto wo = arena::make_unique<tabwriter>(ostrm, opt_args(),
|
||||
auto wo = plib::make_unique<tabwriter, arena>(ostrm, opt_args(),
|
||||
opt_start(), opt_inc(), opt_samples());
|
||||
log_processor::callback_type agcb = log_processor::callback_type(&tabwriter::process, wo.get());
|
||||
|
||||
|
@ -121,7 +121,7 @@ namespace solver
|
||||
{
|
||||
pstring nname(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size())));
|
||||
nl_assert(p->net().is_analog());
|
||||
auto net_proxy_output_u = state().make_pool_object<proxied_analog_output_t>(*this, nname, static_cast<analog_net_t *>(&p->net()));
|
||||
auto net_proxy_output_u = state().make_pool_object<proxied_analog_output_t>(*this, nname, &dynamic_cast<analog_net_t &>(p->net()));
|
||||
net_proxy_output = net_proxy_output_u.get();
|
||||
m_inps.emplace_back(std::move(net_proxy_output_u));
|
||||
}
|
||||
@ -375,6 +375,17 @@ namespace solver
|
||||
m_Idrn.resize(iN, max_count);
|
||||
m_connected_net_Vn.resize(iN, max_count);
|
||||
|
||||
// Initialize arrays to 0 (in case the vrl one is used
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
for (std::size_t j = 0; j < m_terms[k].count(); j++)
|
||||
{
|
||||
m_gtn.set(k,j, nlconst::zero());
|
||||
m_gonn.set(k,j, nlconst::zero());
|
||||
m_Idrn.set(k,j, nlconst::zero());
|
||||
m_connected_net_Vn.set(k, j, nullptr);
|
||||
}
|
||||
|
||||
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
auto count = m_terms[k].count();
|
||||
@ -421,7 +432,7 @@ namespace solver
|
||||
|
||||
void matrix_solver_t::step(netlist_time delta) noexcept
|
||||
{
|
||||
const auto dd(delta.as_fp<nl_fptype>());
|
||||
const auto dd(delta.as_fp<fptype>());
|
||||
for (auto &d : m_step_funcs)
|
||||
d(dd);
|
||||
}
|
||||
@ -478,7 +489,7 @@ namespace solver
|
||||
|
||||
|
||||
if (m_params.m_dynamic_ts)
|
||||
return compute_next_timestep(delta.as_fp<nl_fptype>(), m_params.m_max_timestep);
|
||||
return compute_next_timestep(delta.as_fp<fptype>(), m_params.m_max_timestep);
|
||||
|
||||
return netlist_time::from_fp(m_params.m_max_timestep);
|
||||
}
|
||||
@ -523,7 +534,7 @@ namespace solver
|
||||
return {colmax, colmin};
|
||||
}
|
||||
|
||||
nl_fptype matrix_solver_t::get_weight_around_diag(std::size_t row, std::size_t diag)
|
||||
matrix_solver_t::fptype matrix_solver_t::get_weight_around_diag(std::size_t row, std::size_t diag)
|
||||
{
|
||||
{
|
||||
//
|
||||
@ -532,7 +543,7 @@ namespace solver
|
||||
|
||||
std::vector<bool> touched(1024, false); // FIXME!
|
||||
|
||||
nl_fptype weight = nlconst::zero();
|
||||
fptype weight = nlconst::zero();
|
||||
auto &term = m_terms[row];
|
||||
for (std::size_t i = 0; i < term.count(); i++)
|
||||
{
|
||||
@ -545,7 +556,7 @@ namespace solver
|
||||
if (colu==row) colu = static_cast<unsigned>(diag);
|
||||
else if (colu==diag) colu = static_cast<unsigned>(row);
|
||||
|
||||
weight = weight + plib::abs(static_cast<nl_fptype>(colu) - static_cast<nl_fptype>(diag));
|
||||
weight = weight + plib::abs(static_cast<fptype>(colu) - static_cast<fptype>(diag));
|
||||
touched[colu] = true;
|
||||
}
|
||||
}
|
||||
@ -585,14 +596,14 @@ namespace solver
|
||||
log().verbose(" has {1} dynamic elements", this->dynamic_device_count());
|
||||
log().verbose(" has {1} timestep elements", this->timestep_device_count());
|
||||
log().verbose(" {1:6.3} average newton raphson loops",
|
||||
static_cast<nl_fptype>(this->m_stat_newton_raphson) / static_cast<nl_fptype>(this->m_stat_vsolver_calls));
|
||||
static_cast<fptype>(this->m_stat_newton_raphson) / static_cast<fptype>(this->m_stat_vsolver_calls));
|
||||
log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
|
||||
this->m_stat_calculations,
|
||||
static_cast<nl_fptype>(this->m_stat_calculations) / this->exec().time().as_fp<nl_fptype>(),
|
||||
static_cast<fptype>(this->m_stat_calculations) / this->exec().time().as_fp<fptype>(),
|
||||
this->m_iterative_fail,
|
||||
nlconst::hundred() * static_cast<nl_fptype>(this->m_iterative_fail)
|
||||
/ static_cast<nl_fptype>(this->m_stat_calculations),
|
||||
static_cast<nl_fptype>(this->m_iterative_total) / static_cast<nl_fptype>(this->m_stat_calculations));
|
||||
nlconst::hundred() * static_cast<fptype>(this->m_iterative_fail)
|
||||
/ static_cast<fptype>(this->m_stat_calculations),
|
||||
static_cast<fptype>(this->m_iterative_total) / static_cast<fptype>(this->m_stat_calculations));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "netlist/plib/palloc.h"
|
||||
#include "netlist/plib/penum.h"
|
||||
#include "netlist/plib/pmatrix2d.h"
|
||||
#include "netlist/plib/pmempool.h"
|
||||
#include "netlist/plib/putil.h"
|
||||
#include "netlist/plib/vector_ops.h"
|
||||
|
||||
@ -183,6 +184,8 @@ namespace solver
|
||||
{
|
||||
public:
|
||||
using list_t = std::vector<matrix_solver_t *>;
|
||||
using fptype = nl_fptype;
|
||||
using arena_type = plib::mempool_arena<plib::aligned_arena>;
|
||||
|
||||
// after every call to solve, update inputs must be called.
|
||||
// this can be done as well as a batch to ease parallel processing.
|
||||
@ -259,51 +262,32 @@ namespace solver
|
||||
}
|
||||
|
||||
// return number of floating point operations for solve
|
||||
std::size_t ops() const { return m_ops; }
|
||||
constexpr std::size_t ops() const { return m_ops; }
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
using aligned_alloc = plib::aligned_allocator<T, PALIGN_VECTOROPT>;
|
||||
|
||||
matrix_solver_t(netlist_state_t &anetlist, const pstring &name,
|
||||
const analog_net_t::list_t &nets,
|
||||
const solver_parameters_t *params);
|
||||
|
||||
virtual void vsolve_non_dynamic() = 0;
|
||||
virtual netlist_time compute_next_timestep(nl_fptype cur_ts, nl_fptype max_ts) = 0;
|
||||
virtual bool check_err() = 0;
|
||||
virtual netlist_time compute_next_timestep(fptype cur_ts, fptype max_ts) = 0;
|
||||
virtual bool check_err() const = 0;
|
||||
virtual void store() = 0;
|
||||
|
||||
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gonn;
|
||||
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
|
||||
plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_Idrn;
|
||||
plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
|
||||
|
||||
plib::aligned_vector<terms_for_net_t> m_terms;
|
||||
plib::pmatrix2d_vrl<fptype, arena_type> m_gonn;
|
||||
plib::pmatrix2d_vrl<fptype, arena_type> m_gtn;
|
||||
plib::pmatrix2d_vrl<fptype, arena_type> m_Idrn;
|
||||
plib::pmatrix2d_vrl<fptype *, arena_type> m_connected_net_Vn;
|
||||
|
||||
const solver_parameters_t &m_params;
|
||||
|
||||
state_var<std::size_t> m_iterative_fail;
|
||||
state_var<std::size_t> m_iterative_total;
|
||||
|
||||
plib::aligned_vector<terms_for_net_t> m_terms; // setup only
|
||||
|
||||
private:
|
||||
|
||||
plib::aligned_vector<terms_for_net_t> m_rails_temp;
|
||||
std::vector<device_arena::unique_ptr<proxied_analog_output_t>> m_inps;
|
||||
|
||||
state_var<std::size_t> m_stat_calculations;
|
||||
state_var<std::size_t> m_stat_newton_raphson;
|
||||
state_var<std::size_t> m_stat_vsolver_calls;
|
||||
|
||||
state_var<netlist_time_ext> m_last_step;
|
||||
plib::aligned_vector<nldelegate_ts> m_step_funcs;
|
||||
plib::aligned_vector<nldelegate_dyn> m_dynamic_funcs;
|
||||
|
||||
logic_input_t m_fb_sync;
|
||||
logic_output_t m_Q_sync;
|
||||
|
||||
std::size_t m_ops;
|
||||
|
||||
// base setup - called from constructor
|
||||
void setup_base(setup_t &setup, const analog_net_t::list_t &nets) noexcept(false);
|
||||
|
||||
@ -314,7 +298,7 @@ namespace solver
|
||||
|
||||
int get_net_idx(const analog_net_t *net) const noexcept;
|
||||
std::pair<int, int> get_left_right_of_diag(std::size_t irow, std::size_t idiag);
|
||||
nl_fptype get_weight_around_diag(std::size_t row, std::size_t diag);
|
||||
fptype get_weight_around_diag(std::size_t row, std::size_t diag);
|
||||
|
||||
void add_term(std::size_t net_idx, terminal_t *term) noexcept(false);
|
||||
|
||||
@ -325,272 +309,21 @@ namespace solver
|
||||
|
||||
analog_net_t *get_connected_net(terminal_t *term);
|
||||
|
||||
};
|
||||
state_var<std::size_t> m_stat_calculations;
|
||||
state_var<std::size_t> m_stat_newton_raphson;
|
||||
state_var<std::size_t> m_stat_vsolver_calls;
|
||||
|
||||
template <typename FT, int SIZE>
|
||||
class matrix_solver_ext_t: public matrix_solver_t
|
||||
{
|
||||
public:
|
||||
state_var<netlist_time_ext> m_last_step;
|
||||
plib::aligned_vector<nldelegate_ts> m_step_funcs;
|
||||
plib::aligned_vector<nldelegate_dyn> m_dynamic_funcs;
|
||||
plib::aligned_vector<device_arena::unique_ptr<proxied_analog_output_t>> m_inps;
|
||||
|
||||
using float_type = FT;
|
||||
logic_input_t m_fb_sync;
|
||||
logic_output_t m_Q_sync;
|
||||
|
||||
matrix_solver_ext_t(netlist_state_t &anetlist, const pstring &name,
|
||||
const analog_net_t::list_t &nets,
|
||||
const solver_parameters_t *params, const std::size_t size)
|
||||
: matrix_solver_t(anetlist, name, nets, params)
|
||||
, m_dim(size)
|
||||
, m_new_V(size)
|
||||
, m_RHS(size)
|
||||
, m_mat_ptr(size, this->max_railstart() + 1)
|
||||
, m_last_V(size, nlconst::zero())
|
||||
, m_DD_n_m_1(size, nlconst::zero())
|
||||
, m_h_n_m_1(size, nlconst::magic(1e-6)) // we need a non zero value here
|
||||
{
|
||||
//
|
||||
// save states
|
||||
//
|
||||
state().save(*this, m_last_V.as_base(), this->name(), "m_last_V");
|
||||
state().save(*this, m_DD_n_m_1.as_base(), this->name(), "m_DD_n_m_1");
|
||||
state().save(*this, m_h_n_m_1.as_base(), this->name(), "m_h_n_m_1");
|
||||
}
|
||||
std::size_t m_ops;
|
||||
|
||||
|
||||
private:
|
||||
const std::size_t m_dim;
|
||||
|
||||
protected:
|
||||
static constexpr const std::size_t SIZEABS = plib::parray<FT, SIZE>::SIZEABS();
|
||||
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 0) + 7) / 8) * 8;
|
||||
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::parray<float_type, SIZE> m_new_V;
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::parray<float_type, SIZE> m_RHS;
|
||||
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::pmatrix2d<float_type *> m_mat_ptr;
|
||||
|
||||
// FIXME: below should be private
|
||||
// state - variable time_stepping
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::parray<nl_fptype, SIZE> m_last_V;
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::parray<nl_fptype, SIZE> m_DD_n_m_1;
|
||||
PALIGNAS_VECTOROPT()
|
||||
plib::parray<nl_fptype, SIZE> m_h_n_m_1;
|
||||
|
||||
std::size_t max_railstart() const noexcept
|
||||
{
|
||||
std::size_t max_rail = 0;
|
||||
for (std::size_t k = 0; k < m_terms.size(); k++)
|
||||
max_rail = std::max(max_rail, m_terms[k].railstart());
|
||||
return max_rail;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename M>
|
||||
void log_fill(const T &fill, M &mat)
|
||||
{
|
||||
const std::size_t iN = fill.size();
|
||||
|
||||
// FIXME: Not yet working, mat_cr.h needs some more work
|
||||
#if 0
|
||||
auto mat_GE = dynamic_cast<plib::pGEmatrix_cr_t<typename M::base> *>(&mat);
|
||||
#else
|
||||
plib::unused_var(mat);
|
||||
#endif
|
||||
std::vector<unsigned> levL(iN, 0);
|
||||
std::vector<unsigned> levU(iN, 0);
|
||||
|
||||
// parallel scheme for L x = y
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
unsigned lm=0;
|
||||
for (std::size_t j = 0; j<k; j++)
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
lm = std::max(lm, levL[j]);
|
||||
levL[k] = 1+lm;
|
||||
}
|
||||
|
||||
// parallel scheme for U x = y
|
||||
for (std::size_t k = iN; k-- > 0; )
|
||||
{
|
||||
unsigned lm=0;
|
||||
for (std::size_t j = iN; --j > k; )
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
lm = std::max(lm, levU[j]);
|
||||
levU[k] = 1+lm;
|
||||
}
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
unsigned fm = 0;
|
||||
pstring ml = "";
|
||||
for (std::size_t j = 0; j < iN; j++)
|
||||
{
|
||||
ml += fill[k][j] == 0 ? 'X' : fill[k][j] < M::FILL_INFINITY ? '+' : '.';
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
if (fill[k][j] > fm)
|
||||
fm = fill[k][j];
|
||||
}
|
||||
#if 0
|
||||
this->log().verbose("{1:4} {2} {3:4} {4:4} {5:4} {6:4}", k, ml,
|
||||
levL[k], levU[k], mat_GE ? mat_GE->get_parallel_level(k) : 0, fm);
|
||||
#else
|
||||
this->log().verbose("{1:4} {2} {3:4} {4:4} {5:4} {6:4}", k, ml,
|
||||
levL[k], levU[k], 0, fm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::size_t size() const noexcept
|
||||
{
|
||||
return (SIZE > 0) ? static_cast<std::size_t>(SIZE) : m_dim;
|
||||
}
|
||||
|
||||
#if 1
|
||||
void store() override
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
this->m_terms[i].setV(static_cast<nl_fptype>(m_new_V[i]));
|
||||
}
|
||||
#else
|
||||
// global tanh damping (4.197)
|
||||
// partially cures the symptoms but not the cause
|
||||
void store() override
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
{
|
||||
auto oldV = this->m_terms[i].template getV<nl_fptype>();
|
||||
this->m_terms[i].setV(oldV + 0.02 * plib::tanh((m_new_V[i]-oldV)*50.0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool check_err() override
|
||||
{
|
||||
// NOTE: Ideally we should also include currents (RHS) here. This would
|
||||
// need a reevaluation of the right hand side after voltages have been updated
|
||||
// and thus belong into a different calculation. This applies to all solvers.
|
||||
|
||||
const std::size_t iN = size();
|
||||
const auto reltol(static_cast<float_type>(m_params.m_reltol));
|
||||
const auto vntol(static_cast<float_type>(m_params.m_vntol));
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
{
|
||||
const auto vold(static_cast<float_type>(this->m_terms[i].getV()));
|
||||
const auto vnew(m_new_V[i]);
|
||||
const auto tol(vntol + reltol * std::max(plib::abs(vnew),plib::abs(vold)));
|
||||
if (plib::abs(vnew - vold) > tol)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
netlist_time compute_next_timestep(nl_fptype cur_ts, nl_fptype max_ts) override
|
||||
{
|
||||
nl_fptype new_solver_timestep(max_ts);
|
||||
|
||||
for (std::size_t k = 0; k < size(); k++)
|
||||
{
|
||||
const auto &t = m_terms[k];
|
||||
const auto v(static_cast<nl_fptype>(t.getV()));
|
||||
// avoid floating point exceptions
|
||||
const nl_fptype DD_n = std::max(-fp_constants<nl_fptype>::TIMESTEP_MAXDIFF(),
|
||||
std::min(+fp_constants<nl_fptype>::TIMESTEP_MAXDIFF(),(v - m_last_V[k])));
|
||||
|
||||
m_last_V[k] = v;
|
||||
const nl_fptype hn = cur_ts;
|
||||
|
||||
nl_fptype DD2 = (DD_n / hn - m_DD_n_m_1[k] / m_h_n_m_1[k]) / (hn + m_h_n_m_1[k]);
|
||||
nl_fptype new_net_timestep(0);
|
||||
|
||||
m_h_n_m_1[k] = hn;
|
||||
m_DD_n_m_1[k] = DD_n;
|
||||
if (plib::abs(DD2) > fp_constants<nl_fptype>::TIMESTEP_MINDIV()) // avoid div-by-zero
|
||||
new_net_timestep = plib::sqrt(m_params.m_dynamic_lte / plib::abs(nlconst::half()*DD2));
|
||||
else
|
||||
new_net_timestep = m_params.m_max_timestep;
|
||||
|
||||
new_solver_timestep = std::min(new_net_timestep, new_solver_timestep);
|
||||
}
|
||||
new_solver_timestep = std::max(new_solver_timestep, m_params.m_min_timestep);
|
||||
|
||||
// FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
|
||||
return std::max(netlist_time::from_fp(new_solver_timestep), netlist_time::quantum() * 2);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void build_mat_ptr(M &mat)
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
|
||||
for (std::size_t k=0; k<iN; k++)
|
||||
{
|
||||
std::size_t cnt(0);
|
||||
// build pointers into the compressed row format matrix for each terminal
|
||||
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
|
||||
{
|
||||
int other = this->m_terms[k].m_connected_net_idx[j];
|
||||
if (other >= 0)
|
||||
{
|
||||
m_mat_ptr[k][j] = &(mat[k][static_cast<std::size_t>(other)]);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
nl_assert_always(cnt == this->m_terms[k].railstart(), "Count and railstart mismatch");
|
||||
m_mat_ptr[k][this->m_terms[k].railstart()] = &(mat[k][k]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void clear_square_mat(M &m)
|
||||
{
|
||||
const std::size_t n = size();
|
||||
for (std::size_t k=0; k < n; k++)
|
||||
{
|
||||
auto *p = &(m[k][0]);
|
||||
using mat_elem_type = typename std::decay<decltype(*p)>::type;
|
||||
for (std::size_t i=0; i < n; i++)
|
||||
p[i] = plib::constants<mat_elem_type>::zero();
|
||||
}
|
||||
}
|
||||
|
||||
void fill_matrix_and_rhs()
|
||||
{
|
||||
const std::size_t N = size();
|
||||
|
||||
for (std::size_t k = 0; k < N; k++)
|
||||
{
|
||||
auto &net = m_terms[k];
|
||||
auto **tcr_r = &(m_mat_ptr[k][0]);
|
||||
|
||||
using source_type = typename decltype(m_gtn)::value_type;
|
||||
const std::size_t term_count = net.count();
|
||||
const std::size_t railstart = net.railstart();
|
||||
const auto &go = m_gonn[k];
|
||||
const auto > = m_gtn[k];
|
||||
const auto &Idr = m_Idrn[k];
|
||||
const auto &cnV = m_connected_net_Vn[k];
|
||||
|
||||
// FIXME: gonn, gtn and Idr - which float types should they have?
|
||||
|
||||
auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<source_type>::zero());
|
||||
|
||||
// update diagonal element ...
|
||||
*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
|
||||
|
||||
for (std::size_t i = 0; i < railstart; i++)
|
||||
*tcr_r[i] += static_cast<FT>(go[i]);
|
||||
|
||||
auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<source_type>::zero()));
|
||||
|
||||
for (std::size_t i = railstart; i < term_count; i++)
|
||||
RHS_t += (- go[i]) * *cnV[i];
|
||||
|
||||
m_RHS[k] = static_cast<FT>(RHS_t);
|
||||
}
|
||||
}
|
||||
plib::aligned_vector<terms_for_net_t> m_rails_temp; // setup only
|
||||
|
||||
};
|
||||
|
||||
|
288
src/lib/netlist/solver/nld_matrix_solver_ext.h
Normal file
288
src/lib/netlist/solver/nld_matrix_solver_ext.h
Normal file
@ -0,0 +1,288 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
#ifndef NLD_MATRIX_SOLVER_EXT_H_
|
||||
#define NLD_MATRIX_SOLVER_EXT_H_
|
||||
|
||||
///
|
||||
/// \file nld_matrix_solver.h
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace solver
|
||||
{
|
||||
|
||||
template <typename FT, int SIZE>
|
||||
class matrix_solver_ext_t: public matrix_solver_t
|
||||
{
|
||||
public:
|
||||
|
||||
using float_type = FT;
|
||||
|
||||
matrix_solver_ext_t(netlist_state_t &anetlist, const pstring &name,
|
||||
const analog_net_t::list_t &nets,
|
||||
const solver_parameters_t *params, const std::size_t size)
|
||||
: matrix_solver_t(anetlist, name, nets, params)
|
||||
, m_new_V(size)
|
||||
, m_RHS(size)
|
||||
, m_mat_ptr(size, this->max_railstart() + 1)
|
||||
, m_last_V(size, nlconst::zero())
|
||||
, m_DD_n_m_1(size, nlconst::zero())
|
||||
, m_h_n_m_1(size, nlconst::magic(1e-6)) // we need a non zero value here
|
||||
, m_dim(size)
|
||||
{
|
||||
//
|
||||
// save states
|
||||
//
|
||||
state().save(*this, m_last_V.as_base(), this->name(), "m_last_V");
|
||||
state().save(*this, m_DD_n_m_1.as_base(), this->name(), "m_DD_n_m_1");
|
||||
state().save(*this, m_h_n_m_1.as_base(), this->name(), "m_h_n_m_1");
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr const std::size_t SIZEABS = plib::parray<FT, SIZE>::SIZEABS();
|
||||
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 0) + 7) / 8) * 8;
|
||||
|
||||
//PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray<float_type, SIZE> m_new_V;
|
||||
//PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray<float_type, SIZE> m_RHS;
|
||||
|
||||
//PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::pmatrix2d<float_type *> m_mat_ptr;
|
||||
|
||||
std::size_t max_railstart() const noexcept
|
||||
{
|
||||
std::size_t max_rail = 0;
|
||||
for (std::size_t k = 0; k < m_terms.size(); k++)
|
||||
max_rail = std::max(max_rail, m_terms[k].railstart());
|
||||
return max_rail;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename M>
|
||||
void log_fill(const T &fill, M &mat)
|
||||
{
|
||||
const std::size_t iN = fill.size();
|
||||
|
||||
// FIXME: Not yet working, mat_cr.h needs some more work
|
||||
#if 0
|
||||
auto mat_GE = dynamic_cast<plib::pGEmatrix_cr_t<typename M::base> *>(&mat);
|
||||
#else
|
||||
plib::unused_var(mat);
|
||||
#endif
|
||||
std::vector<unsigned> levL(iN, 0);
|
||||
std::vector<unsigned> levU(iN, 0);
|
||||
|
||||
// parallel scheme for L x = y
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
unsigned lm=0;
|
||||
for (std::size_t j = 0; j<k; j++)
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
lm = std::max(lm, levL[j]);
|
||||
levL[k] = 1+lm;
|
||||
}
|
||||
|
||||
// parallel scheme for U x = y
|
||||
for (std::size_t k = iN; k-- > 0; )
|
||||
{
|
||||
unsigned lm=0;
|
||||
for (std::size_t j = iN; --j > k; )
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
lm = std::max(lm, levU[j]);
|
||||
levU[k] = 1+lm;
|
||||
}
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
unsigned fm = 0;
|
||||
pstring ml = "";
|
||||
for (std::size_t j = 0; j < iN; j++)
|
||||
{
|
||||
ml += fill[k][j] == 0 ? 'X' : fill[k][j] < M::FILL_INFINITY ? '+' : '.';
|
||||
if (fill[k][j] < M::FILL_INFINITY)
|
||||
if (fill[k][j] > fm)
|
||||
fm = fill[k][j];
|
||||
}
|
||||
#if 0
|
||||
this->log().verbose("{1:4} {2} {3:4} {4:4} {5:4} {6:4}", k, ml,
|
||||
levL[k], levU[k], mat_GE ? mat_GE->get_parallel_level(k) : 0, fm);
|
||||
#else
|
||||
this->log().verbose("{1:4} {2} {3:4} {4:4} {5:4} {6:4}", k, ml,
|
||||
levL[k], levU[k], 0, fm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::size_t size() const noexcept
|
||||
{
|
||||
return (SIZE > 0) ? static_cast<std::size_t>(SIZE) : m_dim;
|
||||
}
|
||||
|
||||
#if 1
|
||||
void store() override
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
this->m_terms[i].setV(static_cast<fptype>(m_new_V[i]));
|
||||
}
|
||||
#else
|
||||
// global tanh damping (4.197)
|
||||
// partially cures the symptoms but not the cause
|
||||
void store() override
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
{
|
||||
auto oldV = this->m_terms[i].template getV<fptype>();
|
||||
this->m_terms[i].setV(oldV + 0.02 * plib::tanh((m_new_V[i]-oldV)*50.0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool check_err() const override
|
||||
{
|
||||
// NOTE: Ideally we should also include currents (RHS) here. This would
|
||||
// need a reevaluation of the right hand side after voltages have been updated
|
||||
// and thus belong into a different calculation. This applies to all solvers.
|
||||
|
||||
const std::size_t iN = size();
|
||||
const auto reltol(static_cast<float_type>(m_params.m_reltol));
|
||||
const auto vntol(static_cast<float_type>(m_params.m_vntol));
|
||||
for (std::size_t i = 0; i < iN; i++)
|
||||
{
|
||||
const auto vold(static_cast<float_type>(this->m_terms[i].getV()));
|
||||
const auto vnew(m_new_V[i]);
|
||||
const auto tol(vntol + reltol * std::max(plib::abs(vnew),plib::abs(vold)));
|
||||
if (plib::abs(vnew - vold) > tol)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
netlist_time compute_next_timestep(fptype cur_ts, fptype max_ts) override
|
||||
{
|
||||
fptype new_solver_timestep(max_ts);
|
||||
|
||||
for (std::size_t k = 0; k < size(); k++)
|
||||
{
|
||||
const auto &t = m_terms[k];
|
||||
const auto v(static_cast<fptype>(t.getV()));
|
||||
// avoid floating point exceptions
|
||||
const fptype DD_n = std::max(-fp_constants<fptype>::TIMESTEP_MAXDIFF(),
|
||||
std::min(+fp_constants<fptype>::TIMESTEP_MAXDIFF(),(v - m_last_V[k])));
|
||||
|
||||
m_last_V[k] = v;
|
||||
const fptype hn = cur_ts;
|
||||
|
||||
fptype DD2 = (DD_n / hn - m_DD_n_m_1[k] / m_h_n_m_1[k]) / (hn + m_h_n_m_1[k]);
|
||||
fptype new_net_timestep(0);
|
||||
|
||||
m_h_n_m_1[k] = hn;
|
||||
m_DD_n_m_1[k] = DD_n;
|
||||
if (plib::abs(DD2) > fp_constants<fptype>::TIMESTEP_MINDIV()) // avoid div-by-zero
|
||||
new_net_timestep = plib::sqrt(m_params.m_dynamic_lte / plib::abs(nlconst::half()*DD2));
|
||||
else
|
||||
new_net_timestep = m_params.m_max_timestep;
|
||||
|
||||
new_solver_timestep = std::min(new_net_timestep, new_solver_timestep);
|
||||
}
|
||||
new_solver_timestep = std::max(new_solver_timestep, m_params.m_min_timestep);
|
||||
|
||||
// FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
|
||||
return std::max(netlist_time::from_fp(new_solver_timestep), netlist_time::quantum() * 2);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void build_mat_ptr(M &mat)
|
||||
{
|
||||
const std::size_t iN = size();
|
||||
|
||||
for (std::size_t k=0; k<iN; k++)
|
||||
{
|
||||
std::size_t cnt(0);
|
||||
// build pointers into the compressed row format matrix for each terminal
|
||||
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
|
||||
{
|
||||
int other = this->m_terms[k].m_connected_net_idx[j];
|
||||
if (other >= 0)
|
||||
{
|
||||
m_mat_ptr[k][j] = &(mat[k][static_cast<std::size_t>(other)]);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
nl_assert_always(cnt == this->m_terms[k].railstart(), "Count and railstart mismatch");
|
||||
m_mat_ptr[k][this->m_terms[k].railstart()] = &(mat[k][k]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void clear_square_mat(M &m)
|
||||
{
|
||||
const std::size_t n = size();
|
||||
for (std::size_t k=0; k < n; k++)
|
||||
{
|
||||
auto *p = &(m[k][0]);
|
||||
using mat_elem_type = typename std::decay<decltype(*p)>::type;
|
||||
for (std::size_t i=0; i < n; i++)
|
||||
p[i] = plib::constants<mat_elem_type>::zero();
|
||||
}
|
||||
}
|
||||
|
||||
void fill_matrix_and_rhs()
|
||||
{
|
||||
const std::size_t N = size();
|
||||
|
||||
for (std::size_t k = 0; k < N; k++)
|
||||
{
|
||||
auto &net = m_terms[k];
|
||||
auto **tcr_r = &(m_mat_ptr[k][0]);
|
||||
|
||||
using source_type = typename decltype(m_gtn)::value_type;
|
||||
const std::size_t term_count = net.count();
|
||||
const std::size_t railstart = net.railstart();
|
||||
const auto &go = m_gonn[k];
|
||||
const auto > = m_gtn[k];
|
||||
const auto &Idr = m_Idrn[k];
|
||||
const auto &cnV = m_connected_net_Vn[k];
|
||||
|
||||
// FIXME: gonn, gtn and Idr - which float types should they have?
|
||||
|
||||
auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<source_type>::zero());
|
||||
|
||||
// update diagonal element ...
|
||||
*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
|
||||
|
||||
for (std::size_t i = 0; i < railstart; i++)
|
||||
*tcr_r[i] += static_cast<FT>(go[i]);
|
||||
|
||||
auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<source_type>::zero()));
|
||||
|
||||
for (std::size_t i = railstart; i < term_count; i++)
|
||||
RHS_t += (- go[i]) * *cnV[i];
|
||||
|
||||
m_RHS[k] = static_cast<FT>(RHS_t);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// state - variable time_stepping
|
||||
//PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray<fptype, SIZE> m_last_V;
|
||||
// PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray<fptype, SIZE> m_DD_n_m_1;
|
||||
// PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray<fptype, SIZE> m_h_n_m_1;
|
||||
|
||||
const std::size_t m_dim;
|
||||
|
||||
};
|
||||
|
||||
} // namespace solver
|
||||
} // namespace netlist
|
||||
|
||||
#endif // NLD_MATRIX_SOLVER_EXT_H_
|
@ -13,6 +13,8 @@
|
||||
#include "plib/parray.h"
|
||||
#include "plib/vector_ops.h"
|
||||
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace netlist
|
||||
@ -49,7 +51,7 @@ namespace solver
|
||||
template <typename T>
|
||||
void LE_back_subst(T & x);
|
||||
|
||||
PALIGNAS_VECTOROPT()
|
||||
// PALIGNAS_VECTOROPT() parrays define alignment already
|
||||
plib::parray2D<FT, SIZE, m_pitch_ABS> m_A;
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
/// \file nld_ms_direct1.h
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_ms_direct.h"
|
||||
#include "nld_solver.h"
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
/// \file nld_ms_direct2.h
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_ms_direct.h"
|
||||
#include "nld_solver.h"
|
||||
|
||||
|
@ -12,7 +12,8 @@
|
||||
|
||||
#include "plib/mat_cr.h"
|
||||
|
||||
#include "nld_ms_direct.h"
|
||||
//#include "nld_ms_direct.h"
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_solver.h"
|
||||
#include "plib/pdynlib.h"
|
||||
#include "plib/pstream.h"
|
||||
@ -31,6 +32,8 @@ namespace solver
|
||||
public:
|
||||
|
||||
using mat_type = plib::pGEmatrix_cr_t<plib::pmatrix_cr_t<FT, SIZE>>;
|
||||
using base_type = matrix_solver_ext_t<FT, SIZE>;
|
||||
using fptype = typename base_type::fptype;
|
||||
|
||||
matrix_solver_GCR_t(netlist_state_t &anetlist, const pstring &name,
|
||||
const analog_net_t::list_t &nets,
|
||||
@ -85,9 +88,9 @@ namespace solver
|
||||
|
||||
anetlist.log().verbose("maximum fill: {1}", gr.first);
|
||||
anetlist.log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second,
|
||||
static_cast<nl_fptype>(mat.nz_num) / static_cast<nl_fptype>(iN * iN));
|
||||
static_cast<fptype>(mat.nz_num) / static_cast<fptype>(iN * iN));
|
||||
anetlist.log().verbose(" Pre elimination occupancy ratio: {2}",
|
||||
static_cast<nl_fptype>(raw_elements) / static_cast<nl_fptype>(iN * iN));
|
||||
static_cast<fptype>(raw_elements) / static_cast<fptype>(iN * iN));
|
||||
|
||||
// FIXME: Move me
|
||||
//
|
||||
@ -123,7 +126,7 @@ namespace solver
|
||||
pstring static_compile_name();
|
||||
|
||||
mat_type mat;
|
||||
plib::dynproc<void, FT *, nl_fptype *, nl_fptype *, nl_fptype *, nl_fptype ** > m_proc;
|
||||
plib::dynproc<void, FT *, fptype *, fptype *, fptype *, fptype ** > m_proc;
|
||||
|
||||
};
|
||||
|
||||
@ -139,7 +142,7 @@ namespace solver
|
||||
pstring fpsuffix(fp_constants<FT>::suffix());
|
||||
|
||||
for (std::size_t i = 0; i < mat.nz_num; i++)
|
||||
strm("{1} m_A{2}(0.0);\n", fptype, i, i);
|
||||
strm("\t{1} m_A{2}(0.0);\n", fptype, i, i);
|
||||
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
@ -150,23 +153,27 @@ namespace solver
|
||||
//auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<FT>::zero());
|
||||
//*tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
|
||||
auto pd = this->m_mat_ptr[k][net.railstart()] - &this->mat.A[0];
|
||||
#if 0
|
||||
pstring terms = plib::pfmt("m_A{1} = gt[{2}]")(pd, this->m_gtn.didx(k,0));
|
||||
for (std::size_t i=1; i < net.count(); i++)
|
||||
terms += plib::pfmt(" + gt[{1}]")(this->m_gtn.didx(k,i));
|
||||
|
||||
strm("\t{1};\n", terms);
|
||||
|
||||
#else
|
||||
for (std::size_t i=0; i < net.count(); i++)
|
||||
strm("\tm_A{1} += gt[{2}];\n", pd, this->m_gtn.didx(k,i));
|
||||
#endif
|
||||
//for (std::size_t i = 0; i < railstart; i++)
|
||||
// *tcr_r[i] += static_cast<FT>(go[i]);
|
||||
|
||||
for (std::size_t i = 0; i < net.railstart(); i++)
|
||||
{
|
||||
auto p = this->m_mat_ptr[k][i] - &this->mat.A[0];
|
||||
strm("\tm_A{1} = m_A{1} + go[{2}];\n", p, this->m_gonn.didx(k,i));
|
||||
strm("\tm_A{1} += go[{2}];\n", p, this->m_gonn.didx(k,i));
|
||||
}
|
||||
|
||||
#if 0
|
||||
//auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero()));
|
||||
|
||||
terms = plib::pfmt("{1} RHS{2} = Idr[{3}]")(fptype, k, this->m_Idrn.didx(k,0));
|
||||
for (std::size_t i=1; i < net.count(); i++)
|
||||
terms += plib::pfmt(" + Idr[{1}]")(this->m_Idrn.didx(k,i));
|
||||
@ -174,9 +181,21 @@ namespace solver
|
||||
// RHS_t += (- go[i]) * *cnV[i];
|
||||
|
||||
for (std::size_t i = net.railstart(); i < net.count(); i++)
|
||||
terms += plib::pfmt(" - go[{1}] * *cnV[{1}]")(this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
|
||||
terms += plib::pfmt(" - go[{1}] * *cnV[{2}]")(this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
|
||||
|
||||
strm("\t{1};\n", terms);
|
||||
#else
|
||||
//auto RHS_t(std::accumulate(Idr, Idr + term_count, plib::constants<FT>::zero()));
|
||||
strm("\t{1} RHS{2} = Idr[{3}];\n", fptype, k, this->m_Idrn.didx(k,0));
|
||||
for (std::size_t i=1; i < net.count(); i++)
|
||||
strm("\tRHS{1} += Idr[{2}];\n", k, this->m_Idrn.didx(k,i));
|
||||
//for (std::size_t i = railstart; i < term_count; i++)
|
||||
// RHS_t += (- go[i]) * *cnV[i];
|
||||
|
||||
for (std::size_t i = net.railstart(); i < net.count(); i++)
|
||||
strm("\tRHS{1} -= go[{2}] * *cnV[{3}];\n", k, this->m_gonn.didx(k,i), this->m_connected_net_Vn.didx(k,i));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < iN - 1; i++)
|
||||
@ -188,7 +207,7 @@ namespace solver
|
||||
std::size_t pi = mat.diag[i];
|
||||
|
||||
//const FT f = 1.0 / m_A[pi++];
|
||||
strm("const {1} f{2} = 1.0{3} / m_A{4};\n", fptype, i, fpsuffix, pi);
|
||||
strm("\tconst {1} f{2} = 1.0{3} / m_A{4};\n", fptype, i, fpsuffix, pi);
|
||||
pi++;
|
||||
const std::size_t piie = mat.row_idx[i+1];
|
||||
|
||||
@ -224,6 +243,7 @@ namespace solver
|
||||
strm("\tV[{1}] = RHS{2} / m_A{3};\n", iN - 1, iN - 1, mat.diag[iN - 1]);
|
||||
for (std::size_t j = iN - 1; j-- > 0;)
|
||||
{
|
||||
#if 1
|
||||
strm("\t{1} tmp{2} = 0.0{3};\n", fptype, j, fpsuffix);
|
||||
const std::size_t e = mat.row_idx[j+1];
|
||||
for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++)
|
||||
@ -231,6 +251,24 @@ namespace solver
|
||||
strm("\ttmp{1} += m_A{2} * V[{3}];\n", j, pk, mat.col_idx[pk]);
|
||||
}
|
||||
strm("\tV[{1}] = (RHS{1} - tmp{1}) / m_A{4};\n", j, j, j, mat.diag[j]);
|
||||
#else
|
||||
pstring tmp;
|
||||
const std::size_t e = mat.row_idx[j+1];
|
||||
for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++)
|
||||
{
|
||||
tmp = tmp + plib::pfmt(" + m_A{2} * V[{3}]")(j, pk, mat.col_idx[pk]);
|
||||
}
|
||||
if (tmp.empty())
|
||||
{
|
||||
strm("\tV[{1}] = RHS{1} / m_A{2};\n", j, mat.diag[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//strm("\tconst {1} tmp{2} = {3};\n", fptype, j, tmp.substr(3));
|
||||
//strm("\tV[{1}] = (RHS{1} - tmp{1}) / m_A{2};\n", j, mat.diag[j]);
|
||||
strm("\tV[{1}] = (RHS{1} - ({2})) / m_A{3};\n", j, tmp.substr(3), mat.diag[j]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +276,7 @@ namespace solver
|
||||
pstring matrix_solver_GCR_t<FT, SIZE>::static_compile_name()
|
||||
{
|
||||
pstring str_floattype(fp_constants<FT>::name());
|
||||
pstring str_fptype(fp_constants<nl_fptype>::name());
|
||||
pstring str_fptype(fp_constants<fptype>::name());
|
||||
std::stringstream t;
|
||||
t.imbue(std::locale::classic());
|
||||
plib::putf8_fmt_writer w(&t);
|
||||
@ -255,7 +293,7 @@ namespace solver
|
||||
plib::putf8_fmt_writer strm(&t);
|
||||
pstring name = static_compile_name();
|
||||
pstring str_floattype(fp_constants<FT>::name());
|
||||
pstring str_fptype(fp_constants<nl_fptype>::name());
|
||||
pstring str_fptype(fp_constants<fptype>::name());
|
||||
|
||||
pstring extqual;
|
||||
if (target == CXX_EXTERNAL_C)
|
||||
@ -263,8 +301,8 @@ namespace solver
|
||||
else if (target == CXX_STATIC)
|
||||
extqual = "static";
|
||||
strm.writeline(plib::pfmt("{1} void {2}({3} * __restrict V, "
|
||||
"{4} * __restrict go, {4} * __restrict gt, "
|
||||
"{4} * __restrict Idr, {4} ** __restrict cnV)\n")(extqual, name, str_floattype, str_fptype));
|
||||
"const {4} * __restrict go, const {4} * __restrict gt, "
|
||||
"const {4} * __restrict Idr, const {4} * const * __restrict cnV)\n")(extqual, name, str_floattype, str_fptype));
|
||||
strm.writeline("{\n");
|
||||
generate_code(strm);
|
||||
strm.writeline("}\n");
|
||||
|
@ -8,6 +8,7 @@
|
||||
/// \file nld_ms_gmres.h
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_ms_direct.h"
|
||||
#include "nld_solver.h"
|
||||
#include "plib/gmres.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver.h"
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_solver.h"
|
||||
#include "plib/vector_ops.h"
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
/// Fow w==1 we will do the classic Gauss-Seidel approach.
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_ms_direct.h"
|
||||
#include "nld_solver.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -70,16 +70,19 @@ namespace solver
|
||||
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
nl_fptype gtot_t = nlconst::zero();
|
||||
nl_fptype gabs_t = nlconst::zero();
|
||||
nl_fptype RHS_t = nlconst::zero();
|
||||
|
||||
const std::size_t term_count = this->m_terms[k].count();
|
||||
const nl_fptype * const gt = this->m_gtn[k];
|
||||
const nl_fptype * const go = this->m_gonn[k];
|
||||
const nl_fptype * const Idr = this->m_Idrn[k];
|
||||
const auto * const gt = this->m_gtn[k];
|
||||
const auto * const go = this->m_gonn[k];
|
||||
const auto * const Idr = this->m_Idrn[k];
|
||||
auto other_cur_analog = this->m_connected_net_Vn[k];
|
||||
|
||||
using fpaggtype = std::remove_reference_t<std::remove_cv_t<decltype(this->m_gtn[0][0])>>;
|
||||
|
||||
fpaggtype gtot_t = nlconst_base<fpaggtype>::zero();
|
||||
fpaggtype gabs_t = nlconst_base<fpaggtype>::zero();
|
||||
fpaggtype RHS_t = nlconst_base<fpaggtype>::zero();
|
||||
|
||||
this->m_new_V[k] = static_cast<float_type>(this->m_terms[k].getV());
|
||||
|
||||
for (std::size_t i = 0; i < term_count; i++)
|
||||
@ -126,7 +129,7 @@ namespace solver
|
||||
{
|
||||
const int * net_other = this->m_terms[k].m_connected_net_idx.data();
|
||||
const std::size_t railstart = this->m_terms[k].railstart();
|
||||
const nl_fptype * go = this->m_gonn[k];
|
||||
const auto * go = this->m_gonn[k];
|
||||
|
||||
float_type Idrive = plib::constants<float_type>::zero();
|
||||
for (std::size_t i = 0; i < railstart; i++)
|
||||
|
@ -12,9 +12,8 @@
|
||||
/// For w==1 we will do the classic Gauss-Seidel approach
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver.h"
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "nld_ms_direct.h"
|
||||
#include "nld_solver.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -40,8 +40,7 @@
|
||||
/// introduces numerical instability.
|
||||
///
|
||||
|
||||
#include "nld_matrix_solver.h"
|
||||
#include "nld_solver.h"
|
||||
#include "nld_matrix_solver_ext.h"
|
||||
#include "plib/vector_ops.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -87,7 +87,7 @@ namespace devices
|
||||
analog_net_t::list_t &nets,
|
||||
solver::solver_parameters_t ¶ms, std::size_t size)
|
||||
{
|
||||
return host_arena::make_unique<C>(nl, name, nets, ¶ms, size);
|
||||
return plib::make_unique<C, host_arena>(nl, name, nets, ¶ms, size);
|
||||
}
|
||||
|
||||
template <typename FT, int SIZE>
|
||||
@ -136,29 +136,21 @@ namespace devices
|
||||
switch (net_count)
|
||||
{
|
||||
case 1:
|
||||
return host_arena::make_unique<solver::matrix_solver_direct1_t<FT>>(state(), sname, nets, &m_params);
|
||||
break;
|
||||
return plib::make_unique<solver::matrix_solver_direct1_t<FT>, host_arena>(state(), sname, nets, &m_params);
|
||||
case 2:
|
||||
return host_arena::make_unique<solver::matrix_solver_direct2_t<FT>>(state(), sname, nets, &m_params);
|
||||
break;
|
||||
return plib::make_unique<solver::matrix_solver_direct2_t<FT>, host_arena>(state(), sname, nets, &m_params);
|
||||
case 3:
|
||||
return create_solver<FT, 3>(3, sname, nets);
|
||||
break;
|
||||
case 4:
|
||||
return create_solver<FT, 4>(4, sname, nets);
|
||||
break;
|
||||
case 5:
|
||||
return create_solver<FT, 5>(5, sname, nets);
|
||||
break;
|
||||
case 6:
|
||||
return create_solver<FT, 6>(6, sname, nets);
|
||||
break;
|
||||
case 7:
|
||||
return create_solver<FT, 7>(7, sname, nets);
|
||||
break;
|
||||
case 8:
|
||||
return create_solver<FT, 8>(8, sname, nets);
|
||||
break;
|
||||
default:
|
||||
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
|
||||
if (net_count <= 16)
|
||||
@ -186,7 +178,6 @@ namespace devices
|
||||
return create_solver<FT, -512>(net_count, sname, nets);
|
||||
}
|
||||
return create_solver<FT, 0>(net_count, sname, nets);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +192,7 @@ namespace devices
|
||||
{
|
||||
netlist.log().verbose(" ==> not a rail net");
|
||||
// Must be an analog net
|
||||
auto &n = *static_cast<analog_net_t *>(net.get());
|
||||
auto &n = dynamic_cast<analog_net_t &>(*net);
|
||||
if (!already_processed(n))
|
||||
{
|
||||
groupspre.emplace_back(analog_net_t::list_t());
|
||||
@ -273,9 +264,9 @@ namespace devices
|
||||
// only process analog terminals
|
||||
if (term->is_type(detail::terminal_type::TERMINAL))
|
||||
{
|
||||
auto *pt = static_cast<terminal_t *>(term);
|
||||
auto &pt = dynamic_cast<terminal_t &>(*term);
|
||||
// check the connected terminal
|
||||
analog_net_t &connected_net = netlist.setup().get_connected_terminal(*pt)->net();
|
||||
analog_net_t &connected_net = netlist.setup().get_connected_terminal(pt)->net();
|
||||
netlist.log().verbose(" Connected net {}", connected_net.name());
|
||||
if (!check_if_processed_and_join(connected_net))
|
||||
process_net(netlist, connected_net);
|
||||
@ -306,17 +297,17 @@ namespace devices
|
||||
switch (m_params.m_fp_type())
|
||||
{
|
||||
case solver::matrix_fp_type_e::FLOAT:
|
||||
if (!NL_USE_FLOAT_MATRIX)
|
||||
if (!config::use_float_matrix())
|
||||
log().info("FPTYPE {1} not supported. Using DOUBLE", m_params.m_fp_type().name());
|
||||
ms = create_solvers<std::conditional_t<NL_USE_FLOAT_MATRIX,float, double>>(sname, grp);
|
||||
ms = create_solvers<std::conditional_t<config::use_float_matrix::value, float, double>>(sname, grp);
|
||||
break;
|
||||
case solver::matrix_fp_type_e::DOUBLE:
|
||||
ms = create_solvers<double>(sname, grp);
|
||||
break;
|
||||
case solver::matrix_fp_type_e::LONGDOUBLE:
|
||||
if (!NL_USE_LONG_DOUBLE_MATRIX)
|
||||
if (!config::use_long_double_matrix())
|
||||
log().info("FPTYPE {1} not supported. Using DOUBLE", m_params.m_fp_type().name());
|
||||
ms = create_solvers<std::conditional_t<NL_USE_LONG_DOUBLE_MATRIX, long double, double>>(sname, grp);
|
||||
ms = create_solvers<std::conditional_t<config::use_long_double_matrix::value, long double, double>>(sname, grp);
|
||||
break;
|
||||
case solver::matrix_fp_type_e::FLOATQ128:
|
||||
#if (NL_USE_FLOAT128)
|
||||
@ -355,7 +346,7 @@ namespace devices
|
||||
for (auto & s : m_mat_solvers)
|
||||
{
|
||||
auto r = s->create_solver_code(target);
|
||||
if (r.first != "") // ignore solvers not supporting static compile
|
||||
if (!r.first.empty()) // ignore solvers not supporting static compile
|
||||
mp.push_back(r);
|
||||
}
|
||||
return mp;
|
||||
|
@ -39,7 +39,7 @@ namespace devices
|
||||
void post_start();
|
||||
void stop();
|
||||
|
||||
nl_fptype gmin() const { return m_params.m_gmin(); }
|
||||
auto gmin() const -> decltype(solver::solver_parameters_t::m_gmin()) { return m_params.m_gmin(); }
|
||||
|
||||
solver::static_compile_container create_solver_code(solver::static_compile_target target);
|
||||
|
||||
|
@ -112,7 +112,7 @@ nl_convert_base_t::~nl_convert_base_t()
|
||||
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
|
||||
{
|
||||
pstring pname = devname + "." + name;
|
||||
m_pins.emplace(pname, arena::make_unique<pin_alias_t>(pname, devname + "." + alias));
|
||||
m_pins.emplace(pname, plib::make_unique<pin_alias_t, arena>(pname, devname + "." + alias));
|
||||
}
|
||||
|
||||
void nl_convert_base_t::add_ext_alias(const pstring &alias)
|
||||
@ -138,15 +138,15 @@ void nl_convert_base_t::add_device(arena::unique_ptr<dev_t> dev)
|
||||
|
||||
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
|
||||
{
|
||||
add_device(arena::make_unique<dev_t>(atype, aname, amodel));
|
||||
add_device(plib::make_unique<dev_t, arena>(atype, aname, amodel));
|
||||
}
|
||||
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
|
||||
{
|
||||
add_device(arena::make_unique<dev_t>(atype, aname, aval));
|
||||
add_device(plib::make_unique<dev_t, arena>(atype, aname, aval));
|
||||
}
|
||||
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
|
||||
{
|
||||
add_device(arena::make_unique<dev_t>(atype, aname));
|
||||
add_device(plib::make_unique<dev_t, arena>(atype, aname));
|
||||
}
|
||||
|
||||
void nl_convert_base_t::add_term(const pstring &netname, const pstring &termname)
|
||||
@ -161,7 +161,7 @@ void nl_convert_base_t::add_term(const pstring &netname, const pstring &termname
|
||||
net = m_nets[netname].get();
|
||||
else
|
||||
{
|
||||
auto nets = arena::make_unique<net_t>(netname);
|
||||
auto nets = plib::make_unique<net_t, arena>(netname);
|
||||
net = nets.get();
|
||||
m_nets.emplace(netname, std::move(nets));
|
||||
}
|
||||
@ -245,6 +245,7 @@ void nl_convert_base_t::dump_nl()
|
||||
}
|
||||
|
||||
std::vector<size_t> sorted;
|
||||
sorted.reserve(m_devs.size());
|
||||
for (size_t i=0; i < m_devs.size(); i++)
|
||||
sorted.push_back(i);
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
@ -436,7 +437,7 @@ static int npoly(const pstring &s)
|
||||
|
||||
void nl_convert_spice_t::process_line(const pstring &line)
|
||||
{
|
||||
if (line != "")
|
||||
if (!line.empty())
|
||||
{
|
||||
//printf("// %s\n", line.c_str());
|
||||
std::vector<pstring> tt(plib::psplit(line, " ", true));
|
||||
@ -976,7 +977,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
|
||||
pstring sim = attr["Simulation"];
|
||||
pstring val = attr["Value"];
|
||||
pstring com = attr["Comment"];
|
||||
if (val == "")
|
||||
if (val.empty())
|
||||
val = com;
|
||||
|
||||
if (sim == "CAP")
|
||||
|
Loading…
Reference in New Issue
Block a user