diff options
90 files changed, 4914 insertions, 1521 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 0fa446aa897..c99b5ac9f18 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -503,7 +503,7 @@ void netlist_mame_cpu_device_t::device_start() for (int i=0; i < netlist().m_nets.size(); i++) { - netlist::net_t *n = netlist().m_nets[i].get(); + netlist::detail::net_t *n = netlist().m_nets[i].get(); if (n->is_logic()) { state_add(i*2, n->name().cstr(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr()); @@ -604,7 +604,7 @@ void netlist_mame_sound_device_t::device_start() for (int i=0; i < MAX_OUT; i++) m_out[i] = nullptr; for (int i=0; i < m_num_outputs; i++) { - int chan = outdevs[i]->m_channel.Value(); + int chan = outdevs[i]->m_channel(); netlist().log().verbose("Output %d on channel %d", i, chan); diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index bc31b38dcdd..a7e3da059c2 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -429,7 +429,7 @@ public: inline void write(const UINT32 val) { const UINT32 v = (val >> m_shift) & m_mask; - if (v != m_param->Value()) + if (v != (*m_param)()) synchronize(0, v); } @@ -475,7 +475,7 @@ public: inline void write(const UINT32 val) { const UINT32 v = (val >> m_shift) & 1; - if (v != m_param->Value()) + if (v != (*m_param)()) synchronize(0, v); } @@ -577,7 +577,7 @@ public: NETLIB_UPDATEI() { - nl_double cur = INPANALOG(m_in); + nl_double cur = m_in(); // FIXME: make this a parameter // avoid calls due to noise @@ -637,7 +637,7 @@ public: NETLIB_UPDATEI() { - nl_double val = INPANALOG(m_in) * m_mult.Value() + m_offset.Value(); + nl_double val = m_in() * m_mult() + m_offset(); sound_update(netlist().time()); /* ignore spikes */ if (std::abs(val) < 32767.0) @@ -709,12 +709,12 @@ public: m_pos = 0; for (int i = 0; i < MAX_INPUT_CHANNELS; i++) { - if (m_param_name[i]->Value() != "") + if ((*m_param_name[i])() != pstring("")) { if (i != m_num_channel) netlist().log().fatal("sound input numbering has to be sequential!"); m_num_channel++; - m_param[i] = dynamic_cast<netlist::param_double_t *>(setup().find_param(m_param_name[i]->Value(), true)); + m_param[i] = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_param_name[i])(), true)); } } return m_num_channel; @@ -727,10 +727,10 @@ public: if (m_buffer[i] == nullptr) break; // stop, called outside of stream_update const nl_double v = m_buffer[i][m_pos]; - m_param[i]->setTo(v * m_param_mult[i]->Value() + m_param_offset[i]->Value()); + m_param[i]->setTo(v * (*m_param_mult[i])() + (*m_param_offset[i])()); } m_pos++; - OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); + m_Q.push(!m_Q.net().new_Q(), m_inc ); } public: diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index 8d587c1b80d..1889a88c9aa 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -113,7 +113,7 @@ NETLIB_UPDATE_TERMINALS(QBJT_switch) { const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1); - const int new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0; + const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0; if (m_state_on ^ new_state) { const nl_double gb = new_state ? m_gB : netlist().gmin(); diff --git a/src/lib/netlist/analog/nld_fourterm.cpp b/src/lib/netlist/analog/nld_fourterm.cpp index a077e8d3bcc..31ea09339cf 100644 --- a/src/lib/netlist/analog/nld_fourterm.cpp +++ b/src/lib/netlist/analog/nld_fourterm.cpp @@ -19,8 +19,8 @@ namespace netlist NETLIB_RESET(VCCS) { - const nl_double m_mult = m_G.Value() * m_gfac; // 1.0 ==> 1V ==> 1A - const nl_double GI = NL_FCONST(1.0) / m_RI.Value(); + const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A + const nl_double GI = NL_FCONST(1.0) / m_RI(); m_IP.set(GI); m_IN.set(GI); @@ -66,19 +66,19 @@ NETLIB_UPDATE(LVCCS) NETLIB_UPDATE_TERMINALS(LVCCS) { - const nl_double m_mult = m_G.Value() * m_gfac; // 1.0 ==> 1V ==> 1A + const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A const nl_double vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog(); - if (std::abs(m_mult / m_cur_limit * vi) > 0.5) + if (std::abs(m_mult / m_cur_limit() * vi) > 0.5) m_vi = m_vi + 0.2*std::tanh((vi - m_vi)/0.2); else m_vi = vi; - const nl_double x = m_mult / m_cur_limit * m_vi; + const nl_double x = m_mult / m_cur_limit() * m_vi; const nl_double X = std::tanh(x); const nl_double beta = m_mult * (1.0 - X*X); - const nl_double I = m_cur_limit * X - beta * m_vi; + const nl_double I = m_cur_limit() * X - beta * m_vi; m_OP.set(beta, NL_FCONST(0.0), I); m_OP1.set(-beta, NL_FCONST(0.0)); @@ -112,11 +112,11 @@ NETLIB_UPDATE(CCCS) NETLIB_RESET(VCVS) { - m_gfac = NL_FCONST(1.0) / m_RO.Value(); + m_gfac = NL_FCONST(1.0) / m_RO(); NETLIB_NAME(VCCS)::reset(); - m_OP2.set(NL_FCONST(1.0) / m_RO.Value()); - m_ON2.set(NL_FCONST(1.0) / m_RO.Value()); + m_OP2.set(NL_FCONST(1.0) / m_RO()); + m_ON2.set(NL_FCONST(1.0) / m_RO()); } } //namespace devices diff --git a/src/lib/netlist/analog/nld_fourterm.h b/src/lib/netlist/analog/nld_fourterm.h index 5beba564ee2..7792607cf7a 100644 --- a/src/lib/netlist/analog/nld_fourterm.h +++ b/src/lib/netlist/analog/nld_fourterm.h @@ -157,7 +157,7 @@ public: NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS) , m_gfac(1.0) { - m_gfac = NL_FCONST(1.0) / m_RI.Value(); + m_gfac = NL_FCONST(1.0) / m_RI(); } protected: diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 48a28dfe87c..57d6f6a76f3 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -60,9 +60,9 @@ NETLIB_UPDATE(OPAMP) const double cVt = 0.0258 * 1.0; // * m_n; const double cId = m_model.model_value("DAB"); // 3 mA const double cVd = cVt * std::log(cId / 1e-15 + 1.0); - m_VH.set_Q(INPANALOG(m_VCC) - m_model.model_value("VLH") - cVd); - m_VL.set_Q(INPANALOG(m_GND) + m_model.model_value("VLL") + cVd); - m_VREF.set_Q((INPANALOG(m_VCC) + INPANALOG(m_GND)) / 2.0); + m_VH.push(m_VCC() - m_model.model_value("VLH") - cVd); + m_VL.push(m_GND() + m_model.model_value("VLL") + cVd); + m_VREF.push((m_VCC() + m_GND()) / 2.0); } NETLIB_RESET(OPAMP) diff --git a/src/lib/netlist/analog/nld_opamps.h b/src/lib/netlist/analog/nld_opamps.h index 60e9a6fbe52..5d9825d4b21 100644 --- a/src/lib/netlist/analog/nld_opamps.h +++ b/src/lib/netlist/analog/nld_opamps.h @@ -19,11 +19,11 @@ // Macros // ---------------------------------------------------------------------------------------- -#define OPAMP(name, model) \ - NET_REGISTER_DEV(OPAMP, name) \ +#define OPAMP(name, model) \ + NET_REGISTER_DEV(OPAMP, name) \ NETDEV_PARAMI(name, MODEL, model) -#define LM3900(name) \ +#define LM3900(name) \ SUBMODEL(opamp_lm3900, name) // ---------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ NETLIB_OBJECT(OPAMP) , m_VL(*this, "VL") , m_VREF(*this, "VREF") { - m_type = m_model.model_value("TYPE"); + m_type = static_cast<int>(m_model.model_value("TYPE")); if (m_type == 1) { @@ -117,7 +117,7 @@ private: analog_output_t m_VREF; /* state */ - unsigned m_type; + int m_type; }; } //namespace devices diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp index 639d608dbf2..0bfc4b50512 100644 --- a/src/lib/netlist/analog/nld_switches.cpp +++ b/src/lib/netlist/analog/nld_switches.cpp @@ -26,7 +26,7 @@ NETLIB_RESET(switch1) NETLIB_UPDATE(switch1) { - if (!m_POS.Value()) + if (!m_POS()) { m_R.set_R(R_OFF); } @@ -56,7 +56,7 @@ NETLIB_RESET(switch2) NETLIB_UPDATE(switch2) { - if (!m_POS.Value()) + if (!m_POS()) { m_R1.set_R(R_ON); m_R2.set_R(R_OFF); diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp index b834180eae8..3ddff27557d 100644 --- a/src/lib/netlist/analog/nld_twoterm.cpp +++ b/src/lib/netlist/analog/nld_twoterm.cpp @@ -65,15 +65,15 @@ NETLIB_UPDATE(twoterm) NETLIB_UPDATE_PARAM(POT) { - nl_double v = m_Dial.Value(); - if (m_DialIsLog.Value()) + nl_double v = m_Dial(); + if (m_DialIsLog()) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); m_R1.update_dev(); m_R2.update_dev(); - m_R1.set_R(std::max(m_R.Value() * v, netlist().gmin())); - m_R2.set_R(std::max(m_R.Value() * (NL_FCONST(1.0) - v), netlist().gmin())); + m_R1.set_R(std::max(m_R() * v, netlist().gmin())); + m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), netlist().gmin())); } @@ -83,16 +83,16 @@ NETLIB_UPDATE_PARAM(POT) NETLIB_UPDATE_PARAM(POT2) { - nl_double v = m_Dial.Value(); + nl_double v = m_Dial(); - if (m_DialIsLog.Value()) + if (m_DialIsLog()) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); - if (m_Reverse.Value()) + if (m_Reverse()) v = 1.0 - v; m_R1.update_dev(); - m_R1.set_R(std::max(m_R.Value() * v, netlist().gmin())); + m_R1.set_R(std::max(m_R() * v, netlist().gmin())); } // ---------------------------------------------------------------------------------------- @@ -108,7 +108,7 @@ NETLIB_RESET(C) NETLIB_UPDATE_PARAM(C) { //step_time(1.0/48000.0); - m_GParallel = netlist().gmin() * m_C.Value(); + m_GParallel = netlist().gmin() * m_C(); } NETLIB_UPDATE(C) @@ -146,7 +146,7 @@ NETLIB_UPDATE_TERMINALS(D) NETLIB_RESET(VS) { NETLIB_NAME(twoterm)::reset(); - this->set(1.0 / m_R, m_V, 0.0); + this->set(1.0 / m_R(), m_V(), 0.0); } NETLIB_UPDATE(VS) @@ -161,7 +161,7 @@ NETLIB_UPDATE(VS) NETLIB_RESET(CS) { NETLIB_NAME(twoterm)::reset(); - this->set(0.0, 0.0, m_I); + this->set(0.0, 0.0, m_I()); } NETLIB_UPDATE(CS) diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h index 279bd0d1bf3..b5de48ae1d8 100644 --- a/src/lib/netlist/analog/nld_twoterm.h +++ b/src/lib/netlist/analog/nld_twoterm.h @@ -79,16 +79,17 @@ // FIXME: avoid compile fails // #warning "Do not include rescap.h in a netlist environment" #endif - -#define RES_R(res) ((double)(res)) -#define RES_K(res) ((double)(res) * 1e3) -#define RES_M(res) ((double)(res) * 1e6) -#define CAP_U(cap) ((double)(cap) * 1e-6) -#define CAP_N(cap) ((double)(cap) * 1e-9) -#define CAP_P(cap) ((double)(cap) * 1e-12) -#define IND_U(ind) ((double)(ind) * 1e-6) -#define IND_N(ind) ((double)(ind) * 1e-9) -#define IND_P(ind) ((double)(ind) * 1e-12) +#ifndef RES_R +#define RES_R(res) (static_cast<double>(res)) +#define RES_K(res) (static_cast<double>(res) * 1e3) +#define RES_M(res) (static_cast<double>(res) * 1e6) +#define CAP_U(cap) (static_cast<double>(cap) * 1e-6) +#define CAP_N(cap) (static_cast<double>(cap) * 1e-9) +#define CAP_P(cap) (static_cast<double>(cap) * 1e-12) +#define IND_U(ind) (static_cast<double>(ind) * 1e-6) +#define IND_N(ind) (static_cast<double>(ind) * 1e-9) +#define IND_P(ind) (static_cast<double>(ind) * 1e-12) +#endif // ----------------------------------------------------------------------------- // Implementation @@ -196,8 +197,8 @@ protected: NETLIB_UPDATE_PARAMI() { update_dev(); - if (m_R.Value() > 1e-9) - set_R(m_R.Value()); + if (m_R() > 1e-9) + set_R(m_R()); else set_R(1e-9); } @@ -284,7 +285,7 @@ public: NETLIB_TIMESTEP() { /* Gpar should support convergence */ - const nl_double G = m_C.Value() / step + m_GParallel; + const nl_double G = m_C() / step + m_GParallel; const nl_double I = -G * deltaV(); set(G, 0.0, I); } diff --git a/src/lib/netlist/build/doxygen.conf b/src/lib/netlist/build/doxygen.conf new file mode 100644 index 00000000000..9f0ff127793 --- /dev/null +++ b/src/lib/netlist/build/doxygen.conf @@ -0,0 +1,2427 @@ +# Doxyfile 1.8.11 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "My Project" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxy + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = ../.. + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ".." "../documentation" + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, +# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. + +FILE_PATTERNS = *.h *.cpp + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = "../documentation" + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = "../documentation/doc.css" + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = YES + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: YES. + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, +# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 8b7bc4b2c12..e017e8ef35d 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -162,10 +162,11 @@ depend: .depend .PHONY: clang clang: - $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables" + $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables" -# -Wno-old-style-cast -# FIX: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-old-style-cast -Wno-exit-time-destructors +# +# FIX: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors +# #------------------------------------------------- # generic rules diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index 3f41d6b9daf..f70e229ddff 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -71,7 +71,6 @@ namespace netlist { namespace devices { - static void initialize_factory(factory_list_t &factory) { ENTRY(R, RES, "R") diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp index 3f7dac5e742..a147cf3f58f 100644 --- a/src/lib/netlist/devices/nld_4020.cpp +++ b/src/lib/netlist/devices/nld_4020.cpp @@ -83,14 +83,14 @@ namespace netlist NETLIB_UPDATE(CD4020) { - if (INPLOGIC(m_RESET)) + if (m_RESET()) { m_sub.m_cnt = 0; m_sub.m_IP.inactivate(); /* static */ const netlist_time reset_time = netlist_time::from_nsec(140); - OUTLOGIC(m_sub.m_Q[0], 0, reset_time); - for (int i=3; i<14; i++) - OUTLOGIC(m_sub.m_Q[i], 0, reset_time); + m_sub.m_Q[0].push(0, reset_time); + for (std::size_t i=3; i<14; i++) + m_sub.m_Q[i].push(0, reset_time); } else m_sub.m_IP.activate_hl(); @@ -108,9 +108,9 @@ namespace netlist NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480), }; - OUTLOGIC(m_Q[0], cnt & 1, out_delayQn[0]); - for (int i=3; i<14; i++) - OUTLOGIC(m_Q[i], (cnt >> i) & 1, out_delayQn[i]); + m_Q[0].push(cnt & 1, out_delayQn[0]); + for (std::size_t i=3; i<14; i++) + m_Q[i].push((cnt >> i) & 1, out_delayQn[i]); } NETLIB_DEVICE_IMPL(CD4020) diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index 33b78ddf1b7..a9d82b1e041 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -40,8 +40,8 @@ namespace netlist nl_double sup = (m_supply.vdd() - m_supply.vss()); nl_double low = NL_FCONST(0.45) * sup; nl_double high = NL_FCONST(0.55) * sup; - nl_double in = INPANALOG(m_control) - m_supply.vss(); - nl_double rON = m_base_r * NL_FCONST(5.0) / sup; + nl_double in = m_control() - m_supply.vss(); + nl_double rON = m_base_r() * NL_FCONST(5.0) / sup; nl_double R = -1.0; if (in < low) diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp index 2bdd4653b48..a0ffcfc3fdd 100644 --- a/src/lib/netlist/devices/nld_74107.cpp +++ b/src/lib/netlist/devices/nld_74107.cpp @@ -121,8 +121,8 @@ namespace netlist { const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) }; - OUTLOGIC(m_Q, state, delay[state]); - OUTLOGIC(m_QQ, state ^ 1, delay[state ^ 1]); + m_Q.push(state, delay[state]); + m_QQ.push(state ^ 1, delay[state ^ 1]); } NETLIB_UPDATE(74107Asub) @@ -135,7 +135,7 @@ namespace netlist NETLIB_UPDATE(74107A) { - const auto JK = (INPLOGIC(m_J) << 1) | INPLOGIC(m_K); + const auto JK = (m_J() << 1) | m_K(); switch (JK) { @@ -145,17 +145,17 @@ namespace netlist m_sub.m_F = 0; m_sub.m_clk.inactivate(); break; - case 1: // (!INPLOGIC(m_J) & INPLOGIC(m_K)) + case 1: // (!m_J) & m_K)) m_sub.m_Q1 = 0; m_sub.m_Q2 = 0; m_sub.m_F = 0; break; - case 2: // (INPLOGIC(m_J) & !INPLOGIC(m_K)) + case 2: // (m_J) & !m_K)) m_sub.m_Q1 = 0; m_sub.m_Q2 = 0; m_sub.m_F = 1; break; - case 3: // (INPLOGIC(m_J) & INPLOGIC(m_K)) + case 3: // (m_J) & m_K)) m_sub.m_Q1 = 1; m_sub.m_Q2 = 0; m_sub.m_F = 0; @@ -164,7 +164,7 @@ namespace netlist break; } - if (!INPLOGIC(m_clrQ)) + if (!m_clrQ()) { m_sub.m_clk.inactivate(); m_sub.newstate(0); diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index 5f45b330b61..0e36e2ed487 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -181,47 +181,47 @@ namespace netlist NETLIB_UPDATE(74123) { netlist_sig_t m_trig; - netlist_sig_t res = !INPLOGIC(m_CLRQ); + netlist_sig_t res = !m_CLRQ(); netlist_time t_AB_to_Q = NLTIME_FROM_NS(10); netlist_time t_C_to_Q = NLTIME_FROM_NS(10); if (m_dev_type == 74123) { - m_trig = (INPLOGIC(m_A) ^ 1) & INPLOGIC(m_B) & INPLOGIC(m_CLRQ); + m_trig = (m_A() ^ 1) & m_B() & m_CLRQ(); } else if (m_dev_type == 9602) { - m_trig = (INPLOGIC(m_A) ^ 1) | INPLOGIC(m_B); + m_trig = (m_A() ^ 1) | m_B(); } else // 4538 { - m_trig = (INPLOGIC(m_B) ^ 1) | INPLOGIC(m_A); + m_trig = (m_B() ^ 1) | m_A(); // The line below is from the datasheet truthtable ... doesn't make sense at all - //res = res | INPLOGIC(m_A) | (INPLOGIC(m_B) ^ 1); + //res = res | m_A) | (m_B) ^ 1); t_AB_to_Q = NLTIME_FROM_NS(300); t_C_to_Q = NLTIME_FROM_NS(250); } if (res) { - OUTLOGIC(m_Q, 0, t_C_to_Q); - OUTLOGIC(m_QQ, 1, t_C_to_Q); + m_Q.push(0, t_C_to_Q); + m_QQ.push(1, t_C_to_Q); /* quick charge until trigger */ /* FIXME: SGS datasheet shows quick charge to 5V, * though schematics indicate quick charge to Vhigh only. */ - OUTLOGIC(m_RP_Q, 1, t_C_to_Q); // R_ON - OUTLOGIC(m_RN_Q, 0, t_C_to_Q); // R_OFF + m_RP_Q.push(1, t_C_to_Q); // R_ON + m_RN_Q.push(0, t_C_to_Q); // R_OFF m_state = 2; //charging (quick) } else if (!m_last_trig && m_trig) { // FIXME: Timing! - OUTLOGIC(m_Q, 1, t_AB_to_Q); - OUTLOGIC(m_QQ, 0,t_AB_to_Q); + m_Q.push(1, t_AB_to_Q); + m_QQ.push(0,t_AB_to_Q); - OUTLOGIC(m_RN_Q, 1, t_AB_to_Q); // R_ON - OUTLOGIC(m_RP_Q, 0, t_AB_to_Q); // R_OFF + m_RN_Q.push(1, t_AB_to_Q); // R_ON + m_RP_Q.push(0, t_AB_to_Q); // R_OFF m_state = 1; // discharging } @@ -230,22 +230,22 @@ namespace netlist if (m_state == 1) { - const nl_double vLow = m_KP * TERMANALOG(m_RP.m_R.m_P); - if (INPANALOG(m_CV) < vLow) + const nl_double vLow = m_KP * m_RP.m_R.m_P(); + if (m_CV() < vLow) { - OUTLOGIC(m_RN_Q, 0, NLTIME_FROM_NS(10)); // R_OFF + m_RN_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF m_state = 2; // charging } } if (m_state == 2) { - const nl_double vHigh = TERMANALOG(m_RP.m_R.m_P) * (1.0 - m_KP); - if (INPANALOG(m_CV) > vHigh) + const nl_double vHigh = m_RP.m_R.m_P() * (1.0 - m_KP); + if (m_CV() > vHigh) { - OUTLOGIC(m_RP_Q, 0, NLTIME_FROM_NS(10)); // R_OFF + m_RP_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF - OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10)); - OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10)); + m_Q.push(0, NLTIME_FROM_NS(10)); + m_QQ.push(1, NLTIME_FROM_NS(10)); m_state = 0; // waiting } } @@ -253,7 +253,7 @@ namespace netlist NETLIB_RESET(74123) { - m_KP = 1.0 / (1.0 + exp(m_K.Value())); + m_KP = 1.0 / (1.0 + exp(m_K())); m_RP.do_reset(); m_RN.do_reset(); diff --git a/src/lib/netlist/devices/nld_74153.cpp b/src/lib/netlist/devices/nld_74153.cpp index 5f9df45dfdb..f6ab482d332 100644 --- a/src/lib/netlist/devices/nld_74153.cpp +++ b/src/lib/netlist/devices/nld_74153.cpp @@ -104,28 +104,28 @@ namespace netlist NETLIB_UPDATE(74153sub) { const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) }; - if (!INPLOGIC(m_G)) + if (!m_G()) { - uint_fast8_t t = INPLOGIC(m_C[m_chan]); - OUTLOGIC(m_Y, t, delay[t] ); + auto t = m_C[m_chan](); + m_Y.push(t, delay[t]); } else { - OUTLOGIC(m_Y, 0, delay[0]); + m_Y.push(0, delay[0]); } } NETLIB_UPDATE(74153) { - m_sub.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1)); + m_sub.m_chan = (m_A() | (m_B()<<1)); m_sub.do_update(); } NETLIB_UPDATE(74153_dip) { - m_2.m_chan = m_1.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1)); + m_2.m_chan = m_1.m_chan = (m_A() | (m_B()<<1)); m_1.do_update(); m_2.do_update(); } diff --git a/src/lib/netlist/devices/nld_74175.cpp b/src/lib/netlist/devices/nld_74175.cpp index e927c485e20..4d8e3608ee8 100644 --- a/src/lib/netlist/devices/nld_74175.cpp +++ b/src/lib/netlist/devices/nld_74175.cpp @@ -105,11 +105,11 @@ namespace netlist { if (m_clrq) { - for (int i=0; i<4; i++) + for (std::size_t i=0; i<4; i++) { netlist_sig_t d = (m_data >> i) & 1; - OUTLOGIC(m_Q[i], d, delay[d]); - OUTLOGIC(m_QQ[i], d ^ 1, delay[d ^ 1]); + m_Q[i].push(d, delay[d]); + m_QQ[i].push(d ^ 1, delay[d ^ 1]); } m_CLK.inactivate(); } @@ -118,17 +118,17 @@ namespace netlist NETLIB_UPDATE(74175) { uint_fast8_t d = 0; - for (int i=0; i<4; i++) + for (std::size_t i=0; i<4; i++) { - d |= (INPLOGIC(m_D[i]) << i); + d |= (m_D[i]() << i); } - m_sub.m_clrq = INPLOGIC(m_CLRQ); + m_sub.m_clrq = m_CLRQ(); if (!m_sub.m_clrq) { - for (int i=0; i<4; i++) + for (std::size_t i=0; i<4; i++) { - OUTLOGIC(m_sub.m_Q[i], 0, delay_clear[0]); - OUTLOGIC(m_sub.m_QQ[i], 1, delay_clear[1]); + m_sub.m_Q[i].push(0, delay_clear[0]); + m_sub.m_QQ[i].push(1, delay_clear[1]); } m_sub.m_data = 0; } else if (d != m_sub.m_data) diff --git a/src/lib/netlist/devices/nld_74192.cpp b/src/lib/netlist/devices/nld_74192.cpp index d3f657b93ae..80e1853b7f7 100644 --- a/src/lib/netlist/devices/nld_74192.cpp +++ b/src/lib/netlist/devices/nld_74192.cpp @@ -32,10 +32,9 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - uint_fast8_t read_ABCD() const + unsigned read_ABCD() const { - //return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0); - return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0); + return (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0); } }; @@ -70,7 +69,7 @@ namespace netlist logic_input_t m_CU; logic_input_t m_CD; - state_var<int> m_cnt; + state_var<unsigned> m_cnt; state_var<unsigned> m_last_CU; state_var<unsigned> m_last_CD; @@ -119,25 +118,25 @@ namespace netlist NETLIB_UPDATE(74192) { - int tCarry = 1; - int tBorrow = 1; - if (INPLOGIC(m_CLEAR)) + netlist_sig_t tCarry = 1; + netlist_sig_t tBorrow = 1; + if (m_CLEAR()) { m_cnt = 0; } - else if (!INPLOGIC(m_LOADQ)) + else if (!m_LOADQ()) { m_cnt = m_ABCD.read_ABCD(); } else { - if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU)) + if (m_CD() && !m_last_CU && m_CU()) { m_cnt++; if (m_cnt > MAXCNT) m_cnt = 0; } - if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD)) + if (m_CU() && !m_last_CD && m_CD()) { if (m_cnt > 0) m_cnt--; @@ -146,20 +145,20 @@ namespace netlist } } - if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT)) + if (!m_CU() && (m_cnt == MAXCNT)) tCarry = 0; - if (!INPLOGIC(m_CD) && (m_cnt == 0)) + if (!m_CD() && (m_cnt == 0)) tBorrow = 0; - m_last_CD = INPLOGIC(m_CD); - m_last_CU = INPLOGIC(m_CU); + m_last_CD = m_CD(); + m_last_CU = m_CU(); - for (int i=0; i<4; i++) - OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]); + for (std::size_t i=0; i<4; i++) + m_Q[i].push((m_cnt >> i) & 1, delay[i]); - OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME - OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME + m_BORROWQ.push(tBorrow, NLTIME_FROM_NS(20)); //FIXME + m_CARRYQ.push(tCarry, NLTIME_FROM_NS(20)); //FIXME } NETLIB_DEVICE_IMPL(74192) diff --git a/src/lib/netlist/devices/nld_74193.cpp b/src/lib/netlist/devices/nld_74193.cpp index b6f414a3cba..3d32596dbee 100644 --- a/src/lib/netlist/devices/nld_74193.cpp +++ b/src/lib/netlist/devices/nld_74193.cpp @@ -46,7 +46,7 @@ namespace netlist logic_input_t m_CU; logic_input_t m_CD; - state_var<int> m_cnt; + state_var<unsigned> m_cnt; state_var<unsigned> m_last_CU; state_var<unsigned> m_last_CD; @@ -96,26 +96,26 @@ namespace netlist NETLIB_UPDATE(74193) { - int tCarry = 1; - int tBorrow = 1; - if (INPLOGIC(m_CLEAR)) + netlist_sig_t tCarry = 1; + netlist_sig_t tBorrow = 1; + if (m_CLEAR()) { m_cnt = 0; } - else if (!INPLOGIC(m_LOADQ)) + else if (!m_LOADQ()) { - m_cnt = (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) - | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0); + m_cnt = (m_D() << 3) | (m_C() << 2) + | (m_B() << 1) | (m_A() << 0); } else { - if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU)) + if (m_CD() && !m_last_CU && m_CU()) { m_cnt++; if (m_cnt > MAXCNT) m_cnt = 0; } - if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD)) + if (m_CU() && !m_last_CD && m_CD()) { if (m_cnt > 0) m_cnt--; @@ -124,20 +124,20 @@ namespace netlist } } - if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT)) + if (!m_CU() && (m_cnt == MAXCNT)) tCarry = 0; - if (!INPLOGIC(m_CD) && (m_cnt == 0)) + if (!m_CD() && (m_cnt == 0)) tBorrow = 0; - m_last_CD = INPLOGIC(m_CD); - m_last_CU = INPLOGIC(m_CU); + m_last_CD = m_CD(); + m_last_CU = m_CU(); - for (int i=0; i<4; i++) - OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]); + for (std::size_t i=0; i<4; i++) + m_Q[i].push((m_cnt >> i) & 1, delay[i]); - OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME - OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME + m_BORROWQ.push(tBorrow, NLTIME_FROM_NS(20)); //FIXME + m_CARRYQ.push(tCarry, NLTIME_FROM_NS(20)); //FIXME } NETLIB_DEVICE_IMPL(74193) diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 6b29786bf70..56b322dbc2f 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -37,7 +37,7 @@ namespace netlist NETLIB_UPDATEI(); public: - void update_outputs(uint_fast8_t v); + void update_outputs(unsigned v); static const uint_fast8_t tab7448[16][7]; logic_input_t m_A; @@ -136,18 +136,18 @@ namespace netlist NETLIB_UPDATE(7448) { - if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))) + if (!m_BIQ() || (m_BIQ() && !m_LTQ())) { m_A.inactivate(); m_B.inactivate(); m_C.inactivate(); m_D.inactivate(); m_RBIQ.inactivate(); - if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)) + if (m_BIQ() && !m_LTQ()) { update_outputs(8); } - else if (!INPLOGIC(m_BIQ)) + else if (!m_BIQ()) { update_outputs(15); } @@ -157,10 +157,10 @@ namespace netlist m_C.activate(); m_B.activate(); m_A.activate(); - uint_fast8_t v; + unsigned v; - v = (INPLOGIC(m_A) << 0) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_D) << 3); - if ((!INPLOGIC(m_RBIQ) && (v==0))) + v = (m_A() << 0) | (m_B() << 1) | (m_C() << 2) | (m_D() << 3); + if ((!m_RBIQ() && (v==0))) v = 15; update_outputs(v); } @@ -176,15 +176,15 @@ namespace netlist m_RBIQ.inactivate(); } - NETLIB_FUNC_VOID(7448, update_outputs, (uint_fast8_t v)) + NETLIB_FUNC_VOID(7448, update_outputs, (unsigned v)) { nl_assert(v<16); if (v != m_state) { // max transfer time is 100 NS */ - for (int i=0; i<7; i++) - OUTLOGIC(m_Q[i], tab7448[v][i], NLTIME_FROM_NS(100)); + for (std::size_t i=0; i<7; i++) + m_Q[i].push(tab7448[v][i], NLTIME_FROM_NS(100)); m_state = v; } } diff --git a/src/lib/netlist/devices/nld_7450.cpp b/src/lib/netlist/devices/nld_7450.cpp index 8039014a781..007f899a5f9 100644 --- a/src/lib/netlist/devices/nld_7450.cpp +++ b/src/lib/netlist/devices/nld_7450.cpp @@ -1,4 +1,4 @@ -// license:GPL-2.0+ + // license:GPL-2.0+ // copyright-holders:Couriersud /* * nld_7450.c @@ -67,8 +67,8 @@ namespace netlist m_B.activate(); m_C.activate(); m_D.activate(); - uint_fast8_t t1 = INPLOGIC(m_A) & INPLOGIC(m_B); - uint_fast8_t t2 = INPLOGIC(m_C) & INPLOGIC(m_D); + unsigned t1 = m_A() & m_B(); + unsigned t2 = m_C() & m_D(); const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) }; @@ -91,7 +91,7 @@ namespace netlist m_D.inactivate(); } } - OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000); + m_Q.push(res, times[1 - res]);// ? 22000 : 15000); } NETLIB_DEVICE_IMPL(7450) diff --git a/src/lib/netlist/devices/nld_7474.cpp b/src/lib/netlist/devices/nld_7474.cpp index 41339ebfa4a..f11ccbd2164 100644 --- a/src/lib/netlist/devices/nld_7474.cpp +++ b/src/lib/netlist/devices/nld_7474.cpp @@ -95,8 +95,8 @@ namespace netlist { // 0: High-to-low 40 ns, 1: Low-to-high 25 ns const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) }; - OUTLOGIC(m_Q, stateQ, delay[stateQ]); - OUTLOGIC(m_QQ, stateQQ, delay[stateQQ]); + m_Q.push(stateQ, delay[stateQ]); + m_QQ.push(stateQQ, delay[stateQQ]); } NETLIB_UPDATE(7474sub) @@ -110,19 +110,19 @@ namespace netlist NETLIB_UPDATE(7474) { - if (INPLOGIC(m_PREQ) && INPLOGIC(m_CLRQ)) + if (m_PREQ() && m_CLRQ()) { m_D.activate(); - sub.m_nextD = INPLOGIC(m_D); + sub.m_nextD = m_D(); sub.m_CLK.activate_lh(); } - else if (!INPLOGIC(m_PREQ)) + else if (!m_PREQ()) { sub.newstate(1, 0); sub.m_CLK.inactivate(); m_D.inactivate(); } - else if (!INPLOGIC(m_CLRQ)) + else if (!m_CLRQ()) { sub.newstate(0, 1); sub.m_CLK.inactivate(); diff --git a/src/lib/netlist/devices/nld_7483.cpp b/src/lib/netlist/devices/nld_7483.cpp index a3c7a3ca973..a11f36c1540 100644 --- a/src/lib/netlist/devices/nld_7483.cpp +++ b/src/lib/netlist/devices/nld_7483.cpp @@ -88,19 +88,19 @@ namespace netlist NETLIB_UPDATE(7483) { - uint_fast8_t a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3); - uint_fast8_t b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3); + netlist_sig_t a = (m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3); + netlist_sig_t b = (m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3); - uint_fast8_t r = a + b + INPLOGIC(m_C0); + unsigned r = a + b + m_C0(); if (r != m_lastr) { m_lastr = r; - OUTLOGIC(m_S1, (r >> 0) & 1, NLTIME_FROM_NS(23)); - OUTLOGIC(m_S2, (r >> 1) & 1, NLTIME_FROM_NS(23)); - OUTLOGIC(m_S3, (r >> 2) & 1, NLTIME_FROM_NS(23)); - OUTLOGIC(m_S4, (r >> 3) & 1, NLTIME_FROM_NS(23)); - OUTLOGIC(m_C4, (r >> 4) & 1, NLTIME_FROM_NS(23)); + m_S1.push((r >> 0) & 1, NLTIME_FROM_NS(23)); + m_S2.push((r >> 1) & 1, NLTIME_FROM_NS(23)); + m_S3.push((r >> 2) & 1, NLTIME_FROM_NS(23)); + m_S4.push((r >> 3) & 1, NLTIME_FROM_NS(23)); + m_C4.push((r >> 4) & 1, NLTIME_FROM_NS(23)); } } diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp index f2dd6ff5455..e395c64120e 100644 --- a/src/lib/netlist/devices/nld_7490.cpp +++ b/src/lib/netlist/devices/nld_7490.cpp @@ -41,8 +41,8 @@ namespace netlist logic_input_t m_R92; state_var_u8 m_cnt; - state_var_u8 m_last_A; - state_var_u8 m_last_B; + state_var<netlist_sig_t> m_last_A; + state_var<netlist_sig_t> m_last_B; object_array_t<logic_output_t, 4> m_Q; }; @@ -86,15 +86,15 @@ namespace netlist NETLIB_UPDATE(7490) { - const netlist_sig_t new_A = INPLOGIC(m_A); - const netlist_sig_t new_B = INPLOGIC(m_B); + const netlist_sig_t new_A = m_A(); + const netlist_sig_t new_B = m_B(); - if (INPLOGIC(m_R91) & INPLOGIC(m_R92)) + if (m_R91() & m_R92()) { m_cnt = 9; update_outputs(); } - else if (INPLOGIC(m_R1) & INPLOGIC(m_R2)) + else if (m_R1() & m_R2()) { m_cnt = 0; update_outputs(); @@ -104,7 +104,7 @@ namespace netlist if (m_last_A && !new_A) // High - Low { m_cnt ^= 1; - OUTLOGIC(m_Q[0], m_cnt & 1, delay[0]); + m_Q[0].push(m_cnt & 1, delay[0]); } if (m_last_B && !new_B) // High - Low { @@ -120,8 +120,8 @@ namespace netlist NETLIB_FUNC_VOID(7490, update_outputs, (void)) { - for (int i=0; i<4; i++) - OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]); + for (std::size_t i=0; i<4; i++) + m_Q[i].push((m_cnt >> i) & 1, delay[i]); } NETLIB_DEVICE_IMPL(7490) diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp index 46aec6921af..6e96facabae 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -103,22 +103,22 @@ namespace netlist if (m_reset) { m_state ^= 1; - OUTLOGIC(m_Q, m_state, out_delay); + m_Q.push(m_state, out_delay); } } NETLIB_UPDATE(7493) { - const netlist_sig_t r = INPLOGIC(m_R1) & INPLOGIC(m_R2); + const netlist_sig_t r = m_R1() & m_R2(); if (r) { A.m_I.inactivate(); B.m_I.inactivate(); - OUTLOGIC(A.m_Q, 0, NLTIME_FROM_NS(40)); - OUTLOGIC(B.m_Q, 0, NLTIME_FROM_NS(40)); - OUTLOGIC(C.m_Q, 0, NLTIME_FROM_NS(40)); - OUTLOGIC(D.m_Q, 0, NLTIME_FROM_NS(40)); + A.m_Q.push(0, NLTIME_FROM_NS(40)); + B.m_Q.push(0, NLTIME_FROM_NS(40)); + C.m_Q.push(0, NLTIME_FROM_NS(40)); + D.m_Q.push(0, NLTIME_FROM_NS(40)); A.m_reset = B.m_reset = C.m_reset = D.m_reset = 0; A.m_state = B.m_state = C.m_state = D.m_state = 0; } diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp index 41f81f3cfea..3d35f90eba6 100644 --- a/src/lib/netlist/devices/nld_74ls629.cpp +++ b/src/lib/netlist/devices/nld_74ls629.cpp @@ -160,11 +160,11 @@ namespace netlist if (!m_enableq) { m_out = m_out ^ 1; - OUTLOGIC(m_Y, m_out, m_inc); + m_Y.push(m_out, m_inc); } else { - OUTLOGIC(m_Y, 1, m_inc); + m_Y.push(1, m_inc); } } @@ -174,8 +174,8 @@ namespace netlist // recompute nl_double freq; nl_double v_freq_2, v_freq_3, v_freq_4; - nl_double v_freq = INPANALOG(m_FC); - nl_double v_rng = INPANALOG(m_RNG); + nl_double v_freq = m_FC(); + nl_double v_rng = m_RNG(); /* coefficients */ const nl_double k1 = 1.9904769024796283E+03; @@ -207,27 +207,27 @@ namespace netlist freq += k9 * v_rng * v_freq_3; freq += k10 * v_rng * v_freq_4; - freq *= NL_FCONST(0.1e-6) / m_CAP; + freq *= NL_FCONST(0.1e-6) / m_CAP(); // FIXME: we need a possibility to remove entries from queue ... // or an exact model ... - m_clock.m_inc = netlist_time::from_double(0.5 / (double) freq); + m_clock.m_inc = netlist_time::from_double(0.5 / freq); //m_clock.update(); //NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq)); } - if (!m_clock.m_enableq && INPLOGIC(m_ENQ)) + if (!m_clock.m_enableq && m_ENQ()) { m_clock.m_enableq = 1; m_clock.m_out = m_clock.m_out ^ 1; - OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1)); + m_clock.m_Y.push(m_clock.m_out, netlist_time::from_nsec(1)); } - else if (m_clock.m_enableq && !INPLOGIC(m_ENQ)) + else if (m_clock.m_enableq && !m_ENQ()) { m_clock.m_enableq = 0; m_clock.m_out = m_clock.m_out ^ 1; - OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1)); + m_clock.m_Y.push(m_clock.m_out, netlist_time::from_nsec(1)); } } diff --git a/src/lib/netlist/devices/nld_82S16.cpp b/src/lib/netlist/devices/nld_82S16.cpp index 2f685e37aba..051fcd18ebe 100644 --- a/src/lib/netlist/devices/nld_82S16.cpp +++ b/src/lib/netlist/devices/nld_82S16.cpp @@ -68,33 +68,35 @@ namespace netlist // FIXME: optimize device (separate address decoder!) NETLIB_UPDATE(82S16) { - if (INPLOGIC(m_CE1Q) || INPLOGIC(m_CE2Q) || INPLOGIC(m_CE3Q)) + if (m_CE1Q() || m_CE2Q() || m_CE3Q()) { // FIXME: Outputs are tristate. This needs to be properly implemented - OUTLOGIC(m_DOUTQ, 1, NLTIME_FROM_NS(20)); + m_DOUTQ.push(1, NLTIME_FROM_NS(20)); //for (int i=0; i<8; i++) //m_A[i].inactivate(); } else { unsigned int adr = 0; - for (int i=0; i<8; i++) + for (std::size_t i=0; i<8; i++) { //m_A[i].activate(); - adr |= (INPLOGIC(m_A[i]) << i); + adr |= (m_A[i]() << i); } - if (!INPLOGIC(m_WEQ)) + if (!m_WEQ()) { - m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((uint_fast64_t) 1 << (adr & 0x3f))) | ((uint_fast64_t) INPLOGIC(m_DIN) << (adr & 0x3f)); + m_ram[adr >> 6] = (m_ram[adr >> 6] + & ~(static_cast<uint_fast64_t>(1) << (adr & 0x3f))) + | (static_cast<uint_fast64_t>(m_DIN()) << (adr & 0x3f)); } - OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20)); + m_DOUTQ.push(((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20)); } } NETLIB_RESET(82S16) { - for (int i=0; i<4; i++) + for (std::size_t i=0; i<4; i++) { m_ram[i] = 0; } diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index e7b95549d47..4ddb62af519 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -32,10 +32,9 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - uint_fast8_t read_ABCD() const + unsigned read_ABCD() const { - //return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0); - return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0); + return (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0); } }; @@ -57,8 +56,8 @@ namespace netlist NETLIB_RESETI(); NETLIB_UPDATEI(); public: - inline void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay); - inline void update_outputs(const uint_fast8_t cnt); + inline void update_outputs_all(const unsigned cnt, const netlist_time out_delay); + inline void update_outputs(const unsigned cnt); logic_input_t m_CLK; @@ -70,9 +69,9 @@ namespace netlist logic_output_t m_QD; logic_output_t m_RC; - state_var_u8 m_cnt; - state_var_u8 m_loadq; - state_var_u8 m_ent; + state_var<unsigned> m_cnt; + state_var<netlist_sig_t> m_loadq; + state_var<netlist_sig_t> m_ent; }; NETLIB_OBJECT(9310) @@ -163,11 +162,11 @@ namespace netlist { case MAXCNT - 1: m_cnt = MAXCNT; - OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(20)); - OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20)); + m_RC.push(m_ent, NLTIME_FROM_NS(20)); + m_QA.push(1, NLTIME_FROM_NS(20)); break; case MAXCNT: - OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(20)); + m_RC.push(0, NLTIME_FROM_NS(20)); m_cnt = 0; update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); break; @@ -180,20 +179,20 @@ namespace netlist { m_cnt = m_ABCD->read_ABCD(); update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); - OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } } NETLIB_UPDATE(9310) { - sub.m_loadq = INPLOGIC(m_LOADQ); - sub.m_ent = INPLOGIC(m_ENT); - const netlist_sig_t clrq = INPLOGIC(m_CLRQ); + sub.m_loadq = m_LOADQ(); + sub.m_ent = m_ENT(); + const netlist_sig_t clrq = m_CLRQ(); - if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) && clrq) + if ((!sub.m_loadq || (sub.m_ent & m_ENP())) && clrq) { sub.m_CLK.activate_lh(); - OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } else { @@ -204,56 +203,56 @@ namespace netlist sub.m_cnt = 0; //return; } - OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } } - inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const uint_fast8_t cnt, const netlist_time out_delay)) + inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const unsigned cnt, const netlist_time out_delay)) { - OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay); - OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay); - OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay); - OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay); + m_QA.push((cnt >> 0) & 1, out_delay); + m_QB.push((cnt >> 1) & 1, out_delay); + m_QC.push((cnt >> 2) & 1, out_delay); + m_QD.push((cnt >> 3) & 1, out_delay); } - inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const uint_fast8_t cnt)) + inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const unsigned cnt)) { /* static */ const netlist_time out_delay = NLTIME_FROM_NS(20); #if 0 // for (int i=0; i<4; i++) - // OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]); - OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay); - OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay); - OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay); - OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay); + // m_Q[i], (cnt >> i) & 1, delay[i]); + m_QA, (cnt >> 0) & 1, out_delay); + m_QB, (cnt >> 1) & 1, out_delay); + m_QC, (cnt >> 2) & 1, out_delay); + m_QD, (cnt >> 3) & 1, out_delay); #else if ((cnt & 1) == 1) - OUTLOGIC(m_QA, 1, out_delay); + m_QA.push(1, out_delay); else { - OUTLOGIC(m_QA, 0, out_delay); + m_QA.push(0, out_delay); switch (cnt) { case 0x00: - OUTLOGIC(m_QB, 0, out_delay); - OUTLOGIC(m_QC, 0, out_delay); - OUTLOGIC(m_QD, 0, out_delay); + m_QB.push(0, out_delay); + m_QC.push(0, out_delay); + m_QD.push(0, out_delay); break; case 0x02: case 0x06: case 0x0A: case 0x0E: - OUTLOGIC(m_QB, 1, out_delay); + m_QB.push(1, out_delay); break; case 0x04: case 0x0C: - OUTLOGIC(m_QB, 0, out_delay); - OUTLOGIC(m_QC, 1, out_delay); + m_QB.push(0, out_delay); + m_QC.push(1, out_delay); break; case 0x08: - OUTLOGIC(m_QB, 0, out_delay); - OUTLOGIC(m_QC, 0, out_delay); - OUTLOGIC(m_QD, 1, out_delay); + m_QB.push(0, out_delay); + m_QC.push(0, out_delay); + m_QD.push(1, out_delay); break; } diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 6af7ef2eda9..ea7ca9fc45c 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -32,10 +32,9 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - uint_fast8_t read_ABCD() const + unsigned read_ABCD() const { - //return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0); - return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0); + return (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0); } }; @@ -59,19 +58,19 @@ namespace netlist NETLIB_UPDATEI(); public: - void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay) + void update_outputs_all(const unsigned cnt, const netlist_time out_delay) { - OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay); - OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay); - OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay); - OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay); + m_QA.push((cnt >> 0) & 1, out_delay); + m_QB.push((cnt >> 1) & 1, out_delay); + m_QC.push((cnt >> 2) & 1, out_delay); + m_QD.push((cnt >> 3) & 1, out_delay); } logic_input_t m_CLK; - state_var_u8 m_cnt; - state_var_u8 m_loadq; - state_var_u8 m_ent; + state_var<unsigned> m_cnt; + state_var<netlist_sig_t> m_loadq; + state_var<netlist_sig_t> m_ent; logic_output_t m_QA; logic_output_t m_QB; @@ -166,11 +165,11 @@ namespace netlist { case MAXCNT - 1: m_cnt = MAXCNT; - OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(27)); - OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20)); + m_RC.push(m_ent, NLTIME_FROM_NS(27)); + m_QA.push(1, NLTIME_FROM_NS(20)); break; case MAXCNT: - OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(27)); + m_RC.push(0, NLTIME_FROM_NS(27)); m_cnt = 0; update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); break; @@ -183,21 +182,21 @@ namespace netlist else { m_cnt = m_ABCD->read_ABCD(); - OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); } } NETLIB_UPDATE(9316) { - sub.m_loadq = INPLOGIC(m_LOADQ); - sub.m_ent = INPLOGIC(m_ENT); - const netlist_sig_t clrq = INPLOGIC(m_CLRQ); + sub.m_loadq = m_LOADQ(); + sub.m_ent = m_ENT(); + const netlist_sig_t clrq = m_CLRQ(); - if (((sub.m_loadq ^ 1) | (sub.m_ent & INPLOGIC(m_ENP))) & clrq) + if (((sub.m_loadq ^ 1) | (sub.m_ent & m_ENP())) & clrq) { sub.m_CLK.activate_lh(); - OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } else { @@ -208,7 +207,7 @@ namespace netlist sub.m_cnt = 0; //return; } - OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } } diff --git a/src/lib/netlist/devices/nld_legacy.cpp b/src/lib/netlist/devices/nld_legacy.cpp index e199a2fd371..3a063094b72 100644 --- a/src/lib/netlist/devices/nld_legacy.cpp +++ b/src/lib/netlist/devices/nld_legacy.cpp @@ -56,7 +56,7 @@ namespace netlist param_int_t m_L_to_H; param_int_t m_H_to_L; - state_var_u8 m_last; + state_var<netlist_sig_t> m_last; }; NETLIB_RESET(nicRSFF) @@ -67,15 +67,15 @@ namespace netlist NETLIB_UPDATE(nicRSFF) { - if (!INPLOGIC(m_S)) + if (!m_S()) { - OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(20)); - OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(20)); + m_Q.push(1, NLTIME_FROM_NS(20)); + m_QQ.push(0, NLTIME_FROM_NS(20)); } - else if (!INPLOGIC(m_R)) + else if (!m_R()) { - OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(20)); - OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(20)); + m_Q.push(0, NLTIME_FROM_NS(20)); + m_QQ.push(1, NLTIME_FROM_NS(20)); } } @@ -86,16 +86,16 @@ namespace netlist NETLIB_UPDATE(nicDelay) { - netlist_sig_t nval = INPLOGIC(m_I); + netlist_sig_t nval = m_I(); if (nval && !m_last) { // L_to_H - OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(m_L_to_H.Value())); + m_Q.push(1, NLTIME_FROM_NS(static_cast<unsigned>(m_L_to_H()))); } else if (!nval && m_last) { // H_to_L - OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(m_H_to_L.Value())); + m_Q.push(0, NLTIME_FROM_NS(static_cast<unsigned>(m_H_to_L()))); } m_last = nval; } diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp index b483263a00c..17661de803d 100644 --- a/src/lib/netlist/devices/nld_log.cpp +++ b/src/lib/netlist/devices/nld_log.cpp @@ -28,7 +28,7 @@ namespace netlist NETLIB_UPDATEI() { /* use pstring::sprintf, it is a LOT faster */ - m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) INPANALOG(m_I))); + m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e(static_cast<double>(m_I()))); } NETLIB_RESETI() { } @@ -46,7 +46,7 @@ namespace netlist NETLIB_UPDATEI() { - m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) (INPANALOG(m_I) - INPANALOG(m_I2)))); + m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e(static_cast<double>(m_I() - m_I2()))); } NETLIB_RESETI() { } @@ -79,7 +79,7 @@ namespace netlist NETLIB_UPDATE(wav) { - fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I)); + fprintf(m_file, "%e %e\n", netlist().time().as_double(), m_I()); } NETLIB_NAME(log)::~NETLIB_NAME(wav)() diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index 20239c5e7ea..41d2fea9e34 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -78,7 +78,7 @@ namespace netlist NETLIB_UPDATE(MM5837_dip) { - OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); + m_Q.push(!m_Q.net().new_Q(), m_inc); /* shift register * @@ -94,7 +94,7 @@ namespace netlist if (state != last_state) { const nl_double R = state ? R_HIGH : R_LOW; - const nl_double V = state ? INPANALOG(m_VDD) : INPANALOG(m_VSS); + const nl_double V = state ? m_VDD() : m_VSS(); // We only need to update the net first if this is a time stepping net if (m_is_timestep) diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp index 31b5f091fa4..840dafeb5be 100644 --- a/src/lib/netlist/devices/nld_ne555.cpp +++ b/src/lib/netlist/devices/nld_ne555.cpp @@ -80,7 +80,7 @@ namespace netlist inline nl_double NETLIB_NAME(NE555)::clamp(const nl_double v, const nl_double a, const nl_double b) { nl_double ret = v; - nl_double vcc = TERMANALOG(m_R1.m_P); + nl_double vcc = m_R1.m_P(); if (ret > vcc - a) ret = vcc - a; @@ -108,9 +108,9 @@ namespace netlist { // FIXME: assumes GND is connected to 0V. - nl_double vt = clamp(TERMANALOG(m_R2.m_P), 0.7, 1.4); - bool bthresh = (INPANALOG(m_THRES) > vt); - bool btrig = (INPANALOG(m_TRIG) > clamp(TERMANALOG(m_R2.m_N), 0.7, 1.4)); + nl_double vt = clamp(m_R2.m_P(), 0.7, 1.4); + bool bthresh = (m_THRES() > vt); + bool btrig = (m_TRIG() > clamp(m_R2.m_N(), 0.7, 1.4)); if (!btrig) { @@ -121,19 +121,19 @@ namespace netlist m_ff = false; } - bool out = (!INPLOGIC(m_RESET) ? false : m_ff); + bool out = (!m_RESET() ? false : m_ff); if (m_last_out && !out) { m_RDIS.update_dev(); - OUTANALOG(m_OUT, TERMANALOG(m_R3.m_N)); + m_OUT.push(m_R3.m_N()); m_RDIS.set_R(R_ON); } else if (!m_last_out && out) { m_RDIS.update_dev(); // FIXME: Should be delayed by 100ns - OUTANALOG(m_OUT, TERMANALOG(m_R1.m_P)); + m_OUT.push(m_R1.m_P()); m_RDIS.set_R(R_OFF); } m_last_out = out; diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp index f1aee1ba45d..fa5b89fff46 100644 --- a/src/lib/netlist/devices/nld_r2r_dac.cpp +++ b/src/lib/netlist/devices/nld_r2r_dac.cpp @@ -40,9 +40,10 @@ namespace netlist { update_dev(); - nl_double V = m_VIN.Value() / (nl_double) (1 << m_num.Value()) * (nl_double) m_val.Value(); + double V = m_VIN() / static_cast<double>(1 << m_num()) + * static_cast<double>(m_val()); - this->set(1.0 / m_R.Value(), V, 0.0); + this->set(1.0 / m_R(), V, 0.0); } NETLIB_DEVICE_IMPL(r2r_dac) diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index b692b60506a..e3369e514e5 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -24,12 +24,12 @@ namespace netlist NETLIB_UPDATE_PARAM(clock) { - m_inc = netlist_time::from_hz(m_freq.Value()*2); + m_inc = netlist_time::from_double(1.0 / (m_freq() * 2.0)); } NETLIB_UPDATE(clock) { - OUTLOGIC(m_Q, !INPLOGIC(m_feedback), m_inc ); + m_Q.push(!m_feedback(), m_inc); } // ---------------------------------------------------------------------------------------- @@ -39,13 +39,13 @@ namespace netlist NETLIB_RESET(extclock) { m_cnt = 0; - m_off = netlist_time::from_double(m_offset.Value()); + m_off = netlist_time::from_double(m_offset()); //m_Q.initial(0); } NETLIB_UPDATE(extclock) { - OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off); + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off); m_cnt = (m_cnt + 1) % m_size; m_off = netlist_time::zero(); } @@ -61,7 +61,7 @@ namespace netlist NETLIB_UPDATE(logic_input) { - OUTLOGIC(m_Q, m_IN.Value() & 1, netlist_time::from_nsec(1)); + m_Q.push(m_IN() & 1, netlist_time::from_nsec(1)); } NETLIB_UPDATE_PARAM(logic_input) @@ -79,7 +79,7 @@ namespace netlist NETLIB_UPDATE(analog_input) { - OUTANALOG(m_Q, m_IN.Value()); + m_Q.push(m_IN()); } NETLIB_UPDATE_PARAM(analog_input) @@ -101,7 +101,7 @@ namespace netlist NETLIB_UPDATE(d_to_a_proxy) { - const int state = INPLOGIC(m_I); + const int state = static_cast<int>(m_I()); if (state != m_last_state) { m_last_state = state; @@ -126,11 +126,11 @@ namespace netlist NETLIB_UPDATE(res_sw) { - const int state = INPLOGIC(m_I); + const netlist_sig_t state = m_I(); if (state != m_last_state) { m_last_state = state; - const nl_double R = state ? m_RON.Value() : m_ROFF.Value(); + const nl_double R = state ? m_RON() : m_ROFF(); // We only need to update the net first if this is a time stepping net if ((0)) // m_R->m_P.net().as_analog().solver()->is_timestep()) @@ -163,8 +163,8 @@ namespace netlist //OUTANALOG(m_Q, val); nl_double stack[20]; unsigned ptr = 0; - unsigned e = m_precompiled.size(); - for (unsigned i = 0; i<e; i++) + std::size_t e = m_precompiled.size(); + for (std::size_t i = 0; i<e; i++) { rpn_inst &rc = m_precompiled[i]; switch (rc.m_cmd) @@ -186,14 +186,14 @@ namespace netlist stack[ptr-1] = stack[ptr-1] / stack[ptr]; break; case PUSH_INPUT: - stack[ptr++] = INPANALOG((*m_I[(int) rc.m_param])); + stack[ptr++] = (*m_I[static_cast<unsigned>(rc.m_param)])(); break; case PUSH_CONST: stack[ptr++] = rc.m_param; break; } } - OUTANALOG(m_Q, stack[ptr-1]); + m_Q.push(stack[ptr-1]); } diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp index d885ae3b1ca..c133a29df79 100644 --- a/src/lib/netlist/devices/nld_truthtable.cpp +++ b/src/lib/netlist/devices/nld_truthtable.cpp @@ -32,11 +32,11 @@ namespace netlist typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl; }; - static const uint_least64_t all_set = ~((uint_least64_t) 0); + static const uint_least64_t all_set = ~(static_cast<uint_least64_t>(0)); unsigned truthtable_desc_t::count_bits(uint_least64_t v) { - uint_least64_t ret = 0; + unsigned ret = 0; for (; v != 0; v = v >> 1) { ret += (v & 1); @@ -124,8 +124,8 @@ void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list, uint_least64_t state, uint_least64_t val, std::vector<uint_least8_t> &timing_index) { pstring elem = list[cur].trim(); - int start = 0; - int end = 0; + uint_least64_t start = 0; + uint_least64_t end = 0; if (elem.equals("0")) { @@ -144,7 +144,7 @@ void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list, } else nl_assert_always(false, "unknown input value (not 0, 1, or X)"); - for (int i = start; i <= end; i++) + for (uint_least64_t i = start; i <= end; i++) { const uint_least64_t nstate = state | (i << cur); @@ -205,8 +205,8 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_lea val = val | (1 << j); else nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1"); - netlist_time t = netlist_time::from_nsec(times[j].trim().as_long()); - int k=0; + netlist_time t = netlist_time::from_nsec(static_cast<unsigned long>(times[j].trim().as_long())); + uint_least8_t k=0; while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t) k++; m_timing_nt[k] = t; @@ -228,7 +228,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_lea { if (ign[i] == all_set) { - int tign; + uint_least64_t tign; if ((0)) { tign = get_ignored_simple(i); diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h index a252dbe3bbe..2d3c04e1536 100644 --- a/src/lib/netlist/devices/nld_truthtable.h +++ b/src/lib/netlist/devices/nld_truthtable.h @@ -63,10 +63,10 @@ namespace netlist { switch (m_size) { - case 1: ((uint_least8_t *) m_data)[pos] = val; break; - case 2: ((uint_least16_t *) m_data)[pos] = val; break; - case 4: ((uint_least32_t *) m_data)[pos] = val; break; - case 8: ((uint_least64_t *) m_data)[pos] = val; break; + case 1: static_cast<uint_least8_t *>(m_data)[pos] = static_cast<uint_least8_t>(val); break; + case 2: static_cast<uint_least16_t *>(m_data)[pos] = static_cast<uint_least16_t>(val); break; + case 4: static_cast<uint_least32_t *>(m_data)[pos] = static_cast<uint_least32_t>(val); break; + case 8: static_cast<uint_least64_t *>(m_data)[pos] = static_cast<uint_least64_t>(val); break; default: { } } } @@ -75,10 +75,10 @@ namespace netlist { switch (m_size) { - case 1: return ((uint_least8_t *) m_data)[pos]; break; - case 2: return ((uint_least16_t *) m_data)[pos]; break; - case 4: return ((uint_least32_t *) m_data)[pos]; break; - case 8: return ((uint_least64_t *) m_data)[pos]; break; + case 1: return static_cast<uint_least8_t *>(m_data)[pos]; break; + case 2: return static_cast<uint_least16_t *>(m_data)[pos]; break; + case 4: return static_cast<uint_least32_t *>(m_data)[pos]; break; + case 8: return static_cast<uint_least64_t *>(m_data)[pos]; break; default: return 0; //should never happen } @@ -88,10 +88,10 @@ namespace netlist { switch (m_size) { - case 1: return ((uint_least8_t) val); break; - case 2: return ((uint_least16_t) val); break; - case 4: return ((uint_least32_t) val); break; - case 8: return ((uint_least64_t) val); break; + case 1: return static_cast<uint_least8_t >(val); break; + case 2: return static_cast<uint_least16_t>(val); break; + case 4: return static_cast<uint_least32_t>(val); break; + case 8: return static_cast<uint_least64_t>(val); break; default: return 0; //should never happen } @@ -103,7 +103,7 @@ namespace netlist struct truthtable_desc_t { - truthtable_desc_t(int NO, int NI, bool *initialized, + truthtable_desc_t(unsigned NO, unsigned NI, bool *initialized, packed_int outs, uint_least8_t *timing, netlist_time *timing_nt) : m_NO(NO), m_NI(NI), m_initialized(initialized), m_outs(outs), m_timing(timing), m_timing_nt(timing_nt), @@ -140,7 +140,7 @@ namespace netlist NETLIB_OBJECT(truthtable_t) { private: - family_setter_t m_fam; + detail::family_setter_t m_fam; public: static constexpr int m_num_bits = m_NI; @@ -217,8 +217,8 @@ namespace netlist for (std::size_t i=0; i < m_NO; i++) { pstring tmp = "_" + out[i]; - const int idx = plib::container::indexof(inout, tmp); - if (idx>=0) + const std::size_t idx = plib::container::indexof(inout, tmp); + if (idx != plib::container::npos) { connect_late(m_Q[i], m_I[idx]); // disable ignore for this inputs altogether. @@ -309,7 +309,7 @@ namespace netlist for (std::size_t i = 0; i < m_NI; i++) { m_I[i].activate(); - state |= (INPLOGIC(m_I[i]) << i); + state |= (m_I[i]() << i); mt = std::max(this->m_I[i].net().time(), mt); } else @@ -317,7 +317,7 @@ namespace netlist { if ((ign & 1)) m_I[i].activate(); - state |= (INPLOGIC(m_I[i]) << i); + state |= (m_I[i]() << i); } } else @@ -325,12 +325,12 @@ namespace netlist if (!doOUT) for (std::size_t i = 0; i < m_NI; i++) { - state |= (INPLOGIC(m_I[i]) << i); + state |= (m_I[i]() << i); mt = std::max(this->m_I[i].net().time(), mt); } else for (std::size_t i = 0; i < m_NI; i++) - state |= (INPLOGIC(m_I[i]) << i); + state |= (m_I[i]() << i); } auto nstate = state; @@ -344,7 +344,7 @@ namespace netlist if (doOUT) { for (std::size_t i = 0; i < m_NO; i++) - OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]); + m_Q[i].push((out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]); } else for (std::size_t i = 0; i < m_NO; i++) diff --git a/src/lib/netlist/devices/nlid_cmos.h b/src/lib/netlist/devices/nlid_cmos.h index 758cafa3029..4770eac2164 100644 --- a/src/lib/netlist/devices/nlid_cmos.h +++ b/src/lib/netlist/devices/nlid_cmos.h @@ -26,8 +26,8 @@ namespace netlist NETLIB_RESETI() {} public: - inline nl_double vdd() { return INPANALOG(m_vdd); } - inline nl_double vss() { return INPANALOG(m_vss); } + nl_double vdd() { return m_vdd(); } + nl_double vss() { return m_vss(); } analog_input_t m_vdd; analog_input_t m_vss; diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 9adf43c2234..f16dc42b298 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -49,7 +49,7 @@ namespace netlist , m_Q(*this, "Q") , m_freq(*this, "FREQ", 7159000.0 * 5) { - m_inc = netlist_time::from_hz(m_freq.Value()*2); + m_inc = netlist_time::from_double(1.0 / (m_freq()*2.0)); } NETLIB_RESETI() @@ -59,7 +59,7 @@ namespace netlist NETLIB_UPDATE_PARAMI() { - m_inc = netlist_time::from_hz(m_freq.Value()*2); + m_inc = netlist_time::from_double(1.0 / (m_freq()*2.0)); } NETLIB_UPDATEI() @@ -90,7 +90,7 @@ namespace netlist , m_Q(*this, "Q") , m_freq(*this, "FREQ", 7159000.0 * 5.0) { - m_inc = netlist_time::from_hz(m_freq.Value()*2); + m_inc = netlist_time::from_double(1.0 / (m_freq()*2.0)); connect_late(m_feedback, m_Q); } @@ -121,20 +121,20 @@ namespace netlist , m_cnt(*this, "m_cnt", 0) , m_off(*this, "m_off", netlist_time::zero()) { - m_inc[0] = netlist_time::from_hz(m_freq.Value()*2); + m_inc[0] = netlist_time::from_double(1.0 / (m_freq()*2.0)); connect_late(m_feedback, m_Q); { - netlist_time base = netlist_time::from_hz(m_freq.Value()*2); - plib::pstring_vector_t pat(m_pattern.Value(),","); - m_off = netlist_time::from_double(m_offset.Value()); + netlist_time base = netlist_time::from_double(1.0 / (m_freq()*2.0)); + plib::pstring_vector_t pat(m_pattern(),","); + m_off = netlist_time::from_double(m_offset()); - int pati[256]; + unsigned long pati[256]; m_size = pat.size(); - int total = 0; + unsigned long total = 0; for (unsigned i=0; i<m_size; i++) { - pati[i] = pat[i].as_long(); + pati[i] = static_cast<unsigned long>(pat[i].as_long()); total += pati[i]; } netlist_time ttotal = netlist_time::zero(); @@ -160,7 +160,7 @@ namespace netlist netlist_time m_inc[32]; state_var<unsigned> m_cnt; state_var<netlist_time> m_off; - unsigned m_size; + std::size_t m_size; }; // ----------------------------------------------------------------------------- @@ -175,7 +175,7 @@ namespace netlist /* make sure we get the family first */ , m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)") { - set_logic_family(netlist().setup().family_from_model(m_FAMILY.Value())); + set_logic_family(netlist().setup().family_from_model(m_FAMILY())); } NETLIB_UPDATE_AFTER_PARAM_CHANGE() @@ -220,7 +220,7 @@ namespace netlist } NETLIB_UPDATEI() { - OUTANALOG(m_Q, 0.0); + m_Q.push(0.0); } NETLIB_RESETI() { } protected: @@ -276,13 +276,13 @@ namespace netlist NETLIB_RESETI() { - m_RIN.set(1.0 / m_p_RIN.Value(),0,0); - m_ROUT.set(1.0 / m_p_ROUT.Value(),0,0); + m_RIN.set(1.0 / m_p_RIN(),0,0); + m_ROUT.set(1.0 / m_p_ROUT(),0,0); } NETLIB_UPDATEI() { - OUTANALOG(m_Q, INPANALOG(m_I)); + m_Q.push(m_I()); } private: @@ -309,10 +309,10 @@ namespace netlist , m_func(*this, "FUNC", "") , m_Q(*this, "Q") { - for (int i=0; i < m_N; i++) + for (int i=0; i < m_N(); i++) m_I.push_back(plib::make_unique<analog_input_t>(*this, plib::pfmt("A{1}")(i))); - plib::pstring_vector_t cmds(m_func.Value(), " "); + plib::pstring_vector_t cmds(m_func(), " "); m_precompiled.clear(); for (std::size_t i=0; i < cmds.size(); i++) @@ -338,7 +338,7 @@ namespace netlist rc.m_cmd = PUSH_CONST; rc.m_param = cmd.as_double(&err); if (err) - netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value()); + netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func()); } m_precompiled.push_back(rc); } @@ -404,13 +404,13 @@ namespace netlist NETLIB_RESETI() { m_last_state = 0; - m_R.set_R(m_ROFF.Value()); + m_R.set_R(m_ROFF()); } //NETLIB_UPDATE_PARAMI(); NETLIB_UPDATEI(); private: - state_var_u8 m_last_state; + state_var<netlist_sig_t> m_last_state; }; // ----------------------------------------------------------------------------- @@ -420,7 +420,8 @@ namespace netlist NETLIB_OBJECT(base_proxy) { public: - nld_base_proxy(netlist_t &anetlist, const pstring &name, logic_t *inout_proxied, core_terminal_t *proxy_inout) + nld_base_proxy(netlist_t &anetlist, const pstring &name, + logic_t *inout_proxied, detail::core_terminal_t *proxy_inout) : device_t(anetlist, name) { m_logic_family = inout_proxied->logic_family(); @@ -431,7 +432,7 @@ namespace netlist virtual ~nld_base_proxy() {} logic_t &term_proxied() const { return *m_term_proxied; } - core_terminal_t &proxy_term() const { return *m_proxy_term; } + detail::core_terminal_t &proxy_term() const { return *m_proxy_term; } protected: @@ -443,7 +444,7 @@ namespace netlist private: const logic_family_desc_t *m_logic_family; logic_t *m_term_proxied; - core_terminal_t *m_proxy_term; + detail::core_terminal_t *m_proxy_term; }; // ----------------------------------------------------------------------------- @@ -472,9 +473,9 @@ namespace netlist NETLIB_UPDATEI() { if (m_I.Q_Analog() > logic_family().m_high_thresh_V) - OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1)); + m_Q.push(1, NLTIME_FROM_NS(1)); else if (m_I.Q_Analog() < logic_family().m_low_thresh_V) - OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1)); + m_Q.push(0, NLTIME_FROM_NS(1)); else { // do nothing @@ -495,7 +496,8 @@ namespace netlist virtual logic_input_t &in() { return m_I; } protected: - nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied, core_terminal_t &proxy_out) + nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, + logic_output_t *out_proxied, detail::core_terminal_t &proxy_out) : nld_base_proxy(anetlist, name, out_proxied, &proxy_out) , m_I(*this, "I") { diff --git a/src/lib/netlist/documentation/doc.css b/src/lib/netlist/documentation/doc.css new file mode 100644 index 00000000000..fa415f1d252 --- /dev/null +++ b/src/lib/netlist/documentation/doc.css @@ -0,0 +1,14 @@ +img[alt*="-50r."] +{ + width: 30%; + display: block; + float: right; +} +.fragment +{ + clear: both; +} +.footer +{ + clear: both; +} diff --git a/src/lib/netlist/documentation/mainpage.dox.h b/src/lib/netlist/documentation/mainpage.dox.h new file mode 100644 index 00000000000..75df1a18065 --- /dev/null +++ b/src/lib/netlist/documentation/mainpage.dox.h @@ -0,0 +1,165 @@ + +/*! \mainpage notitle + +##Netlist + +###A mixed signal circuit simulation. + +- D: Device +- O: Rail output (output) +- I: Infinite impedance input (input) +- T: Terminal (finite impedance) + +The following example shows a typical connection between several devices: + + +---+ +---+ +---+ +---+ +---+ + | | | | | | | | | | + | D | | D | | D | | D | | D | + | | | | | | | | | | + +-O-+ +-I-+ +-I-+ +-T-+ +-T-+ + | | | | | + +-+---------+---------+---------+---------+-+ + | rail net | + +-------------------------------------------+ + +A rail net is a net which is driven by exactly one output with an +(idealized) internal resistance of zero. +Ideally, it can deliver infinite current. + +A infinite resistance input does not source or sink current. + +Terminals source or sink finite (but never zero) current. + +The system differentiates between analog and logic input and outputs and +analog terminals. Analog and logic devices can not be connected to the +same net. Instead, proxy devices are inserted automatically: + + +---+ +---+ + | | | | + | D1| | D2| + | A | | L | + +-O-+ +-I-+ + | | + +-+---------+---+ + | rail net | + +---------------+ + +is converted into + + +----------+ + | | + +---+ +-+-+ | +---+ + | | | L | A-L | | | + | D1| | D | Proxy | | D2| + | A | | A | | | | + +-O-+ +-I-+ | +-I-+ + | | | | + +-+---------+--+ +-+-----+-------+ + | rail net (A) | | rail net (L) | + +--------------| +---------------+ + +This works both analog to logic as well as logic to analog. + +The above is an advanced implementation of the existing discrete +subsystem in MAME. Instead of relying on a fixed time-step, analog devices +could either connect to fixed time-step clock or use an internal clock +to update them. This would however introduce macro devices for RC, diodes +and transistors again. + +Instead, the following approach in case of a pure terminal/input network +is taken: + + +---+ +---+ +---+ +---+ +---+ + | | | | | | | | | | + | D | | D | | D | | D | | D | + | | | | | | | | | | + +-T-+ +-I-+ +-I-+ +-T-+ +-T-+ + | | | | | + '+' | | '-' '-' + +-+---------+---------+---------+---------+-+ + | Calculated net | + +-------------------------------------------+ + +Netlist uses the following basic two terminal device: + + (k) + +-----T-----+ + | | | + | +--+--+ | + | | | | + | R | | + | R | | + | R I | + | | I | Device n + | V+ I | + | V | | + | V- | | + | | | | + | +--+--+ | + | | | + +-----T-----+ + (l) + +This is a resistance in series to a voltage source and paralleled by a +current source. This is suitable to model voltage sources, current sources, +resistors, capacitors, inductances and diodes. + +\f[ + I_{n,l} = - I_{n,k} = ( V_k - V^N - V_l ) \frac{1}{R^n} + I^n +\f] + +Now, the sum of all currents for a given net must be 0: + +\f[ + \sum_n I_{n,l} = 0 = \sum_{n,k} (V_k - V^n - V_l ) \frac{1}{R^n} + I^n +\f] + +With \f$ G^n = \frac{1}{R^n} \f$ and \f$ \sum_n G^n = G^{tot} \f$ and \f$k=k(n)\f$ + +\f[ + 0 = - V_l G^{tot} + \sum_n (V_{k(n)} - V^n) G^n + I^n) +\f] + +and with \f$ l=l(n)\f$ and fixed \f$ k\f$ + +\f[ + 0 = -V_k G^{tot} + sum_n( V_{l(n)} + V^n ) G^n - I^n) +\f] + +These equations represent a linear Matrix equation (with more math). + +In the end the solution of the analog subsystem boils down to + +\f[ + \mathbf{\it{(G - D) v = i}} +\f] + +with G being the conductance matrix, D a diagonal matrix with the total +conductance on the diagonal elements, V the net voltage vector and I the +current vector. + +By using solely two terminal devices, we can simplify the whole calculation +significantly. A BJT now is a four terminal device with two terminals being +connected internally. + +The system is solved using an iterative approach: + +G V - D V = I + +assuming V=Vn=Vo + +Vn = D-1 (I - G Vo) + +Each terminal thus has three properties: + +a) Resistance +b) Voltage source +c) Current source/sink + +Going forward, the approach can be extended e.g. to use a linear +equation solver. + +The formal representation of the circuit will stay the same, thus scales. + + +*/ diff --git a/src/lib/netlist/documentation/primer_1.dox.h b/src/lib/netlist/documentation/primer_1.dox.h new file mode 100644 index 00000000000..8df612e242d --- /dev/null +++ b/src/lib/netlist/documentation/primer_1.dox.h @@ -0,0 +1,62 @@ +/*! \page primer_1 nltool primer + +## First example + +Let's start with a simple charge/discharge circuit. I denotes the input, +O denotes the output. + + I >----RRR----+-----> O + | + C + C + C + | + GND + +Now in netlist syntax this looks like: + +~~~{.cpp} +NETLIST_START(charge_discharge) + SOLVER(solver, 48000) // Fixed frequency solver + CLOCK(I, 200) // 200 Hz clock as input, TTL logic output + RES(R, RES_K(1)) + CAP(C, CAP_U(1)) + + NET_C(I.Q, R.1) + NET_C(R.2, C.1) + NET_C(C.2, GND) + + ALIAS(O, R.2) // Output O == C.1 == R.2 +NETLIST_END() +~~~ + +Save this example as e.g. test1.cpp. Now that's a c++ extension. The background +is simple. You can also compile netlists. Thats a feature which is used by MAME. +That's something we will cover later. + +Now, to test this, run the following: + +~~~ +> nltool --cmd=run -f test1.cpp -t 0.05 -l O -l I +~~~ + +This will run the circuit for 50 ms and log input "I" to file log_I.log and +output "O" to log_O.log . The log files will be located in the current folder. + +Next, run + +~~~ +> plot_nl I O +~~~ + + + +and enjoy the results. + +##Recap + +We have created our first netlist fragment. nltool was used to model the +periodically forced charge/discharge circuit for 50ms. Finally we plotted both input +and output voltages using the plot_nl command using the log files we generated. + +*/ diff --git a/src/lib/netlist/documentation/structure.dox.h b/src/lib/netlist/documentation/structure.dox.h new file mode 100644 index 00000000000..41dd9507717 --- /dev/null +++ b/src/lib/netlist/documentation/structure.dox.h @@ -0,0 +1,21 @@ + +/*! The netlist namespace. + * All netlist related code is contained in the netlist namespace + */ +namespace netlist +{ + /*! The netlist::devices namespace. + * All netlist devices are contained in the netlist::devices namespace. + */ + namespace devices + { + } + + /*! Internal support classes you should not use in code using netlist api. + * This namespace contains all internal support classes not intended + * to be used outside of the core. + */ + namespace detail + { + } +} diff --git a/src/lib/netlist/documentation/test1-50r.svg b/src/lib/netlist/documentation/test1-50r.svg new file mode 100644 index 00000000000..ea4f70f6efe --- /dev/null +++ b/src/lib/netlist/documentation/test1-50r.svg @@ -0,0 +1,720 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg + width="600" height="480" + viewBox="0 0 600 480" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" +> + +<title>Gnuplot</title> +<desc>Produced by GNUPLOT 4.6 patchlevel 6 </desc> + +<g id="gnuplot_canvas"> + +<rect x="0" y="0" width="600" height="480" fill="none"/> +<defs> + + <circle id='gpDot' r='0.5' stroke-width='0.5'/> + <path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/> + <path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/> + <path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/> + <rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/> + <rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/> + <circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/> + <use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/> + <path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/> + <use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/> + <use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/> + <use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/> + <use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/> + <use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/> + <filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'> + <feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/> + <feComposite in='SourceGraphic' in2='grey' operator='atop'/> + </filter> +</defs> +<g style="fill:none; color:white; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter"> +</g> +<g style="fill:none; color:black; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter"> + <path stroke='black' d='M53.9,444.0 L62.9,444.0 M575.0,444.0 L566.0,444.0 '/> <g transform="translate(45.6,448.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 0</text> + </g> + <path stroke='black' d='M53.9,390.6 L62.9,390.6 M575.0,390.6 L566.0,390.6 '/> <g transform="translate(45.6,395.1)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 0.5</text> + </g> + <path stroke='black' d='M53.9,337.2 L62.9,337.2 M575.0,337.2 L566.0,337.2 '/> <g transform="translate(45.6,341.7)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 1</text> + </g> + <path stroke='black' d='M53.9,283.8 L62.9,283.8 M575.0,283.8 L566.0,283.8 '/> <g transform="translate(45.6,288.3)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 1.5</text> + </g> + <path stroke='black' d='M53.9,230.3 L62.9,230.3 M575.0,230.3 L566.0,230.3 '/> <g transform="translate(45.6,234.8)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 2</text> + </g> + <path stroke='black' d='M53.9,176.9 L62.9,176.9 M575.0,176.9 L566.0,176.9 '/> <g transform="translate(45.6,181.4)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 2.5</text> + </g> + <path stroke='black' d='M53.9,123.5 L62.9,123.5 M575.0,123.5 L566.0,123.5 '/> <g transform="translate(45.6,128.0)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 3</text> + </g> + <path stroke='black' d='M53.9,70.1 L62.9,70.1 M575.0,70.1 L566.0,70.1 '/> <g transform="translate(45.6,74.6)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 3.5</text> + </g> + <path stroke='black' d='M53.9,16.7 L62.9,16.7 M575.0,16.7 L566.0,16.7 '/> <g transform="translate(45.6,21.2)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text> 4</text> + </g> + <path stroke='black' d='M53.9,444.0 L53.9,435.0 M53.9,16.7 L53.9,25.7 '/> <g transform="translate(53.9,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>0 </text> + </g> + <path stroke='black' d='M106.0,444.0 L106.0,435.0 M106.0,16.7 L106.0,25.7 '/> <g transform="translate(106.0,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>5m</text> + </g> + <path stroke='black' d='M158.1,444.0 L158.1,435.0 M158.1,16.7 L158.1,25.7 '/> <g transform="translate(158.1,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>10m</text> + </g> + <path stroke='black' d='M210.2,444.0 L210.2,435.0 M210.2,16.7 L210.2,25.7 '/> <g transform="translate(210.2,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>15m</text> + </g> + <path stroke='black' d='M262.3,444.0 L262.3,435.0 M262.3,16.7 L262.3,25.7 '/> <g transform="translate(262.3,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>20m</text> + </g> + <path stroke='black' d='M314.5,444.0 L314.5,435.0 M314.5,16.7 L314.5,25.7 '/> <g transform="translate(314.5,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>25m</text> + </g> + <path stroke='black' d='M366.6,444.0 L366.6,435.0 M366.6,16.7 L366.6,25.7 '/> <g transform="translate(366.6,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>30m</text> + </g> + <path stroke='black' d='M418.7,444.0 L418.7,435.0 M418.7,16.7 L418.7,25.7 '/> <g transform="translate(418.7,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>35m</text> + </g> + <path stroke='black' d='M470.8,444.0 L470.8,435.0 M470.8,16.7 L470.8,25.7 '/> <g transform="translate(470.8,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>40m</text> + </g> + <path stroke='black' d='M522.9,444.0 L522.9,435.0 M522.9,16.7 L522.9,25.7 '/> <g transform="translate(522.9,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>45m</text> + </g> + <path stroke='black' d='M575.0,444.0 L575.0,435.0 M575.0,16.7 L575.0,25.7 '/> <g transform="translate(575.0,466.5)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:middle"> + <text>50m</text> + </g> + <path stroke='black' d='M53.9,16.7 L53.9,444.0 L575.0,444.0 L575.0,16.7 L53.9,16.7 Z '/></g> + <g id="gnuplot_plot_1" ><title>gnuplot_plot_1</title> +<g style="fill:none; color:red; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter"> + <g transform="translate(507.9,39.2)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text>O</text> + </g> + <path d='M516.2,34.7 L558.4,34.7 M53.9,444.0 L54.1,444.0 L54.1,443.8 L54.3,443.8 L54.3,443.6 L54.6,443.6 + L54.6,443.4 L54.8,443.4 L54.8,443.2 L55.0,443.2 L55.0,443.0 L55.2,443.0 L55.2,442.8 L55.4,442.8 + L55.4,442.6 L55.6,442.6 L55.6,442.4 L55.9,442.4 L55.9,442.2 L56.1,442.2 L56.1,442.0 L56.3,442.0 + L56.3,441.8 L56.5,441.8 L56.5,441.7 L56.7,441.7 L56.7,441.5 L56.9,441.5 L56.9,441.3 L57.2,441.3 + L57.2,441.2 L57.4,441.2 L57.4,441.0 L57.6,441.0 L57.6,440.8 L57.8,440.8 L57.8,440.7 L58.0,440.7 + L58.0,440.5 L58.2,440.5 L58.2,440.4 L58.5,440.4 L58.5,440.2 L58.7,440.2 L58.7,440.1 L58.9,440.1 + L58.9,440.0 L59.1,440.0 L59.1,439.8 L59.3,439.8 L59.3,439.7 L59.5,439.7 L59.5,439.6 L59.8,439.6 + L59.8,439.4 L60.0,439.4 L60.0,439.3 L60.2,439.3 L60.2,439.2 L60.4,439.2 L60.4,439.1 L60.6,439.1 + L60.6,439.0 L60.8,439.0 L60.8,438.8 L61.1,438.8 L61.1,438.7 L61.3,438.7 L61.3,438.6 L61.5,438.6 + L61.5,438.5 L61.7,438.5 L61.7,438.4 L61.9,438.4 L61.9,438.3 L62.2,438.3 L62.2,438.2 L62.4,438.2 + L62.4,438.1 L62.6,438.1 L62.6,438.0 L62.8,438.0 L62.8,437.9 L63.0,437.9 L63.0,437.8 L63.2,437.8 + L63.2,437.7 L63.5,437.7 L63.5,437.6 L63.7,437.6 L63.7,437.5 L63.9,437.5 L64.1,437.5 L64.1,437.4 + L64.3,437.4 L64.3,437.3 L64.5,437.3 L64.5,437.2 L64.8,437.2 L64.8,437.1 L65.0,437.1 L65.2,437.1 + L65.2,437.0 L65.4,437.0 L65.4,436.9 L65.6,436.9 L65.6,436.8 L65.8,436.8 L66.1,436.8 L66.1,436.7 + L66.3,436.7 L66.3,436.6 L66.5,436.6 L66.7,436.6 L66.7,436.5 L66.9,436.5 L66.9,436.4 L67.1,436.4 + L67.4,436.4 L67.4,436.3 L67.6,436.3 L67.6,436.2 L67.8,436.2 L68.0,436.2 L68.0,436.1 L68.2,436.1 + L68.4,436.1 L68.4,436.0 L68.7,436.0 L68.7,435.9 L68.9,435.9 L69.1,435.9 L69.1,435.8 L69.3,435.8 + L69.5,435.8 L69.5,435.7 L69.7,435.7 L70.0,435.7 L70.0,435.6 L70.2,435.6 L70.4,435.6 L70.4,435.5 + L70.6,435.5 L70.8,435.5 L71.1,435.5 L71.1,435.4 L71.3,435.4 L71.5,435.4 L71.5,435.3 L71.7,435.3 + L71.9,435.3 L72.1,435.3 L72.1,435.2 L72.4,435.2 L72.6,435.2 L72.6,435.1 L72.8,435.1 L73.0,435.1 + L73.2,435.1 L73.2,435.0 L73.4,435.0 L73.7,435.0 L73.9,435.0 L73.9,434.9 L74.1,434.9 L74.3,434.9 + L74.5,434.9 L74.5,434.8 L74.7,434.8 L75.0,434.8 L75.2,434.8 L75.2,434.7 L75.4,434.7 L75.6,434.7 + L75.8,434.7 L76.0,434.7 L76.0,434.6 L76.3,434.6 L76.5,434.6 L76.7,434.6 L76.7,434.5 L76.9,434.5 + L77.1,434.5 L77.3,434.5 L77.6,434.5 L77.6,434.4 L77.8,434.4 L78.0,434.4 L78.2,434.4 L78.4,434.4 + L78.7,434.4 L78.7,434.3 L78.9,434.3 L79.1,434.3 L79.3,434.3 L79.5,434.3 L79.7,434.3 L79.7,434.2 + L80.0,434.2 L80.2,434.2 L80.2,426.7 L80.4,426.7 L80.4,419.3 L80.6,419.3 L80.6,412.0 L80.8,412.0 + L80.8,404.8 L81.0,404.8 L81.0,397.8 L81.3,397.8 L81.3,390.9 L81.5,390.9 L81.5,384.1 L81.7,384.1 + L81.7,377.5 L81.9,377.5 L81.9,370.9 L82.1,370.9 L82.1,364.5 L82.3,364.5 L82.3,358.2 L82.6,358.2 + L82.6,352.0 L82.8,352.0 L82.8,346.0 L83.0,346.0 L83.0,340.0 L83.2,340.0 L83.2,334.2 L83.4,334.2 + L83.4,328.4 L83.6,328.4 L83.6,322.8 L83.9,322.8 L83.9,317.2 L84.1,317.2 L84.1,311.8 L84.3,311.8 + L84.3,306.4 L84.5,306.4 L84.5,301.2 L84.7,301.2 L84.7,296.0 L84.9,296.0 L84.9,291.0 L85.2,291.0 + L85.2,286.0 L85.4,286.0 L85.4,281.2 L85.6,281.2 L85.6,276.4 L85.8,276.4 L85.8,271.7 L86.0,271.7 + L86.0,267.0 L86.3,267.0 L86.3,262.5 L86.5,262.5 L86.5,258.1 L86.7,258.1 L86.7,253.7 L86.9,253.7 + L86.9,249.4 L87.1,249.4 L87.1,245.2 L87.3,245.2 L87.3,241.1 L87.6,241.1 L87.6,237.0 L87.8,237.0 + L87.8,233.0 L88.0,233.0 L88.0,229.1 L88.2,229.1 L88.2,225.2 L88.4,225.2 L88.4,221.5 L88.6,221.5 + L88.6,217.8 L88.9,217.8 L88.9,214.1 L89.1,214.1 L89.1,210.6 L89.3,210.6 L89.3,207.0 L89.5,207.0 + L89.5,203.6 L89.7,203.6 L89.7,200.2 L89.9,200.2 L89.9,196.9 L90.2,196.9 L90.2,193.6 L90.4,193.6 + L90.4,190.4 L90.6,190.4 L90.6,187.3 L90.8,187.3 L90.8,184.2 L91.0,184.2 L91.0,181.2 L91.2,181.2 + L91.2,178.2 L91.5,178.2 L91.5,175.3 L91.7,175.3 L91.7,172.4 L91.9,172.4 L91.9,169.6 L92.1,169.6 + L92.1,166.8 L92.3,166.8 L92.3,164.1 L92.5,164.1 L92.5,161.4 L92.8,161.4 L92.8,158.8 L93.0,158.8 + L93.0,156.2 L93.2,156.2 L93.2,153.7 L93.4,153.7 L93.4,151.2 L93.6,151.2 L93.6,148.8 L93.9,148.8 + L93.9,146.4 L94.1,146.4 L94.1,144.0 L94.3,144.0 L94.3,141.7 L94.5,141.7 L94.5,139.5 L94.7,139.5 + L94.7,137.3 L94.9,137.3 L94.9,135.1 L95.2,135.1 L95.2,132.9 L95.4,132.9 L95.4,130.8 L95.6,130.8 + L95.6,128.8 L95.8,128.8 L95.8,126.7 L96.0,126.7 L96.0,124.7 L96.2,124.7 L96.2,122.8 L96.5,122.8 + L96.5,120.9 L96.7,120.9 L96.7,119.0 L96.9,119.0 L96.9,117.1 L97.1,117.1 L97.1,115.3 L97.3,115.3 + L97.3,113.5 L97.5,113.5 L97.5,111.8 L97.8,111.8 L97.8,110.1 L98.0,110.1 L98.0,108.4 L98.2,108.4 + L98.2,106.7 L98.4,106.7 L98.4,105.1 L98.6,105.1 L98.6,103.5 L98.8,103.5 L98.8,101.9 L99.1,101.9 + L99.1,100.4 L99.3,100.4 L99.3,98.8 L99.5,98.8 L99.5,97.4 L99.7,97.4 L99.7,95.9 L99.9,95.9 + L99.9,94.5 L100.1,94.5 L100.1,93.1 L100.4,93.1 L100.4,91.7 L100.6,91.7 L100.6,90.3 L100.8,90.3 + L100.8,89.0 L101.0,89.0 L101.0,87.7 L101.2,87.7 L101.2,86.4 L101.4,86.4 L101.4,85.1 L101.7,85.1 + L101.7,83.9 L101.9,83.9 L101.9,82.7 L102.1,82.7 L102.1,81.5 L102.3,81.5 L102.3,80.3 L102.5,80.3 + L102.5,79.2 L102.8,79.2 L102.8,78.0 L103.0,78.0 L103.0,76.9 L103.2,76.9 L103.2,75.8 L103.4,75.8 + L103.4,74.8 L103.6,74.8 L103.6,73.7 L103.8,73.7 L103.8,72.7 L104.1,72.7 L104.1,71.7 L104.3,71.7 + L104.3,70.7 L104.5,70.7 L104.5,69.7 L104.7,69.7 L104.7,68.7 L104.9,68.7 L104.9,67.8 L105.1,67.8 + L105.1,66.9 L105.4,66.9 L105.4,66.0 L105.6,66.0 L105.6,65.1 L105.8,65.1 L105.8,64.2 L106.0,64.2 + L106.0,63.3 L106.2,63.3 L106.2,70.8 L106.4,70.8 L106.4,78.2 L106.7,78.2 L106.7,85.5 L106.9,85.5 + L106.9,92.6 L107.1,92.6 L107.1,99.5 L107.3,99.5 L107.3,106.3 L107.5,106.3 L107.5,113.0 L107.7,113.0 + L107.7,119.5 L108.0,119.5 L108.0,125.9 L108.2,125.9 L108.2,132.2 L108.4,132.2 L108.4,138.3 L108.6,138.3 + L108.6,144.3 L108.8,144.3 L108.8,150.2 L109.0,150.2 L109.0,156.0 L109.3,156.0 L109.3,161.6 L109.5,161.6 + L109.5,167.2 L109.7,167.2 L109.7,172.6 L109.9,172.6 L109.9,177.9 L110.1,177.9 L110.1,183.1 L110.4,183.1 + L110.4,188.2 L110.6,188.2 L110.6,193.2 L110.8,193.2 L110.8,198.1 L111.0,198.1 L111.0,202.9 L111.2,202.9 + L111.2,207.6 L111.4,207.6 L111.4,212.2 L111.7,212.2 L111.7,216.7 L111.9,216.7 L111.9,221.1 L112.1,221.1 + L112.1,225.5 L112.3,225.5 L112.3,229.7 L112.5,229.7 L112.5,233.9 L112.7,233.9 L112.7,237.9 L113.0,237.9 + L113.0,241.9 L113.2,241.9 L113.2,245.8 L113.4,245.8 L113.4,249.6 L113.6,249.6 L113.6,253.4 L113.8,253.4 + L113.8,257.0 L114.0,257.0 L114.0,260.6 L114.3,260.6 L114.3,264.2 L114.5,264.2 L114.5,267.6 L114.7,267.6 + L114.7,271.0 L114.9,271.0 L114.9,274.3 L115.1,274.3 L115.1,277.5 L115.3,277.5 L115.3,280.7 L115.6,280.7 + L115.6,283.8 L115.8,283.8 L115.8,286.9 L116.0,286.9 L116.0,289.9 L116.2,289.9 L116.2,292.8 L116.4,292.8 + L116.4,295.7 L116.6,295.7 L116.6,298.5 L116.9,298.5 L116.9,301.2 L117.1,301.2 L117.1,303.9 L117.3,303.9 + L117.3,306.5 L117.5,306.5 L117.5,309.1 L117.7,309.1 L117.7,311.7 L118.0,311.7 L118.0,314.1 L118.2,314.1 + L118.2,316.6 L118.4,316.6 L118.4,318.9 L118.6,318.9 L118.6,321.3 L118.8,321.3 L118.8,323.6 L119.0,323.6 + L119.0,325.8 L119.3,325.8 L119.3,328.0 L119.5,328.0 L119.5,330.1 L119.7,330.1 L119.7,332.2 L119.9,332.2 + L119.9,334.3 L120.1,334.3 L120.1,336.3 L120.3,336.3 L120.3,338.3 L120.6,338.3 L120.6,340.2 L120.8,340.2 + L120.8,342.1 L121.0,342.1 L121.0,344.0 L121.2,344.0 L121.2,345.8 L121.4,345.8 L121.4,347.6 L121.6,347.6 + L121.6,349.3 L121.9,349.3 L121.9,351.1 L122.1,351.1 L122.1,352.7 L122.3,352.7 L122.3,354.4 L122.5,354.4 + L122.5,356.0 L122.7,356.0 L122.7,357.6 L122.9,357.6 L122.9,359.1 L123.2,359.1 L123.2,360.6 L123.4,360.6 + L123.4,362.1 L123.6,362.1 L123.6,363.6 L123.8,363.6 L123.8,365.0 L124.0,365.0 L124.0,366.4 L124.2,366.4 + L124.2,367.7 L124.5,367.7 L124.5,369.1 L124.7,369.1 L124.7,370.4 L124.9,370.4 L124.9,371.7 L125.1,371.7 + L125.1,372.9 L125.3,372.9 L125.3,374.2 L125.6,374.2 L125.6,375.4 L125.8,375.4 L125.8,376.5 L126.0,376.5 + L126.0,377.7 L126.2,377.7 L126.2,378.8 L126.4,378.8 L126.4,379.9 L126.6,379.9 L126.6,381.0 L126.9,381.0 + L126.9,382.1 L127.1,382.1 L127.1,383.1 L127.3,383.1 L127.3,384.2 L127.5,384.2 L127.5,385.2 L127.7,385.2 + L127.7,386.1 L127.9,386.1 L127.9,387.1 L128.2,387.1 L128.2,388.1 L128.4,388.1 L128.4,389.0 L128.6,389.0 + L128.6,389.9 L128.8,389.9 L128.8,390.8 L129.0,390.8 L129.0,391.6 L129.2,391.6 L129.2,392.5 L129.5,392.5 + L129.5,393.3 L129.7,393.3 L129.7,394.1 L129.9,394.1 L129.9,394.9 L130.1,394.9 L130.1,395.7 L130.3,395.7 + L130.3,396.5 L130.5,396.5 L130.5,397.2 L130.8,397.2 L130.8,398.0 L131.0,398.0 L131.0,398.7 L131.2,398.7 + L131.2,399.4 L131.4,399.4 L131.4,400.1 L131.6,400.1 L131.6,400.8 L131.8,400.8 L131.8,401.4 L132.1,401.4 + L132.1,402.1 L132.3,402.1 L132.3,395.1 L132.5,395.1 L132.5,388.3 L132.7,388.3 L132.7,381.6 L132.9,381.6 + L132.9,375.0 L133.1,375.0 L133.1,368.5 L133.4,368.5 L133.4,362.1 L133.6,362.1 L133.6,355.9 L133.8,355.9 + L133.8,349.7 L134.0,349.7 L134.0,343.7 L134.2,343.7 L134.2,337.8 L134.5,337.8 L134.5,332.0 L134.7,332.0 + L134.7,326.2 L134.9,326.2 L134.9,320.6 L135.1,320.6 L135.1,315.1 L135.3,315.1 L135.3,309.7 L135.5,309.7 + L135.5,304.4 L135.8,304.4 L135.8,299.2 L136.0,299.2 L136.0,294.1 L136.2,294.1 L136.2,289.1 L136.4,289.1 + L136.4,284.2 L136.6,284.2 L136.6,279.3 L136.8,279.3 L136.8,274.6 L137.1,274.6 L137.1,269.9 L137.3,269.9 + L137.3,265.3 L137.5,265.3 L137.5,260.8 L137.7,260.8 L137.7,256.4 L137.9,256.4 L137.9,252.1 L138.1,252.1 + L138.1,247.8 L138.4,247.8 L138.4,243.6 L138.6,243.6 L138.6,239.5 L138.8,239.5 L138.8,235.5 L139.0,235.5 + L139.0,231.5 L139.2,231.5 L139.2,227.6 L139.4,227.6 L139.4,223.8 L139.7,223.8 L139.7,220.1 L139.9,220.1 + L139.9,216.4 L140.1,216.4 L140.1,212.8 L140.3,212.8 L140.3,209.2 L140.5,209.2 L140.5,205.7 L140.7,205.7 + L140.7,202.3 L141.0,202.3 L141.0,198.9 L141.2,198.9 L141.2,195.6 L141.4,195.6 L141.4,192.4 L141.6,192.4 + L141.6,189.2 L141.8,189.2 L141.8,186.1 L142.1,186.1 L142.1,183.0 L142.3,183.0 L142.3,180.0 L142.5,180.0 + L142.5,177.1 L142.7,177.1 L142.7,174.2 L142.9,174.2 L142.9,171.3 L143.1,171.3 L143.1,168.5 L143.4,168.5 + L143.4,165.8 L143.6,165.8 L143.6,163.1 L143.8,163.1 L143.8,160.4 L144.0,160.4 L144.0,157.8 L144.2,157.8 + L144.2,155.3 L144.4,155.3 L144.4,152.8 L144.7,152.8 L144.7,150.3 L144.9,150.3 L144.9,147.9 L145.1,147.9 + L145.1,145.5 L145.3,145.5 L145.3,143.2 L145.5,143.2 L145.5,140.9 L145.7,140.9 L145.7,138.6 L146.0,138.6 + L146.0,136.4 L146.2,136.4 L146.2,134.3 L146.4,134.3 L146.4,132.1 L146.6,132.1 L146.6,130.0 L146.8,130.0 + L146.8,128.0 L147.0,128.0 L147.0,126.0 L147.3,126.0 L147.3,124.0 L147.5,124.0 L147.5,122.0 L147.7,122.0 + L147.7,120.1 L147.9,120.1 L147.9,118.3 L148.1,118.3 L148.1,116.4 L148.3,116.4 L148.3,114.6 L148.6,114.6 + L148.6,112.9 L148.8,112.9 L148.8,111.1 L149.0,111.1 L149.0,109.4 L149.2,109.4 L149.2,107.7 L149.4,107.7 + L149.4,106.1 L149.7,106.1 L149.7,104.5 L149.9,104.5 L149.9,102.9 L150.1,102.9 L150.1,101.3 L150.3,101.3 + L150.3,99.8 L150.5,99.8 L150.5,98.3 L150.7,98.3 L150.7,96.8 L151.0,96.8 L151.0,95.3 L151.2,95.3 + L151.2,93.9 L151.4,93.9 L151.4,92.5 L151.6,92.5 L151.6,91.2 L151.8,91.2 L151.8,89.8 L152.0,89.8 + L152.0,88.5 L152.3,88.5 L152.3,87.2 L152.5,87.2 L152.5,85.9 L152.7,85.9 L152.7,84.7 L152.9,84.7 + L152.9,83.4 L153.1,83.4 L153.1,82.2 L153.3,82.2 L153.3,81.0 L153.6,81.0 L153.6,79.9 L153.8,79.9 + L153.8,78.7 L154.0,78.7 L154.0,77.6 L154.2,77.6 L154.2,76.5 L154.4,76.5 L154.4,75.4 L154.6,75.4 + L154.6,74.4 L154.9,74.4 L154.9,73.3 L155.1,73.3 L155.1,72.3 L155.3,72.3 L155.3,71.3 L155.5,71.3 + L155.5,70.3 L155.7,70.3 L155.7,69.3 L155.9,69.3 L155.9,68.4 L156.2,68.4 L156.2,67.4 L156.4,67.4 + L156.4,66.5 L156.6,66.5 L156.6,65.6 L156.8,65.6 L156.8,64.7 L157.0,64.7 L157.0,63.9 L157.2,63.9 + L157.2,63.0 L157.5,63.0 L157.5,62.2 L157.7,62.2 L157.7,61.3 L157.9,61.3 L157.9,60.5 L158.1,60.5 + L158.1,59.7 L158.3,59.7 L158.3,67.3 L158.6,67.3 L158.6,74.8 L158.8,74.8 L158.8,82.1 L159.0,82.1 + L159.0,89.2 L159.2,89.2 L159.2,96.2 L159.4,96.2 L159.4,103.1 L159.6,103.1 L159.6,109.8 L159.9,109.8 + L159.9,116.4 L160.1,116.4 L160.1,122.9 L160.3,122.9 L160.3,129.2 L160.5,129.2 L160.5,135.4 L160.7,135.4 + L160.7,141.5 L160.9,141.5 L160.9,147.5 L161.2,147.5 L161.2,153.3 L161.4,153.3 L161.4,159.0 L161.6,159.0 + L161.6,164.6 L161.8,164.6 L161.8,170.1 L162.0,170.1 L162.0,175.4 L162.2,175.4 L162.2,180.7 L162.5,180.7 + L162.5,185.8 L162.7,185.8 L162.7,190.9 L162.9,190.9 L162.9,195.8 L163.1,195.8 L163.1,200.7 L163.3,200.7 + L163.3,205.4 L163.5,205.4 L163.5,210.1 L163.8,210.1 L163.8,214.6 L164.0,214.6 L164.0,219.1 L164.2,219.1 + L164.2,223.4 L164.4,223.4 L164.4,227.7 L164.6,227.7 L164.6,231.9 L164.8,231.9 L164.8,236.0 L165.1,236.0 + L165.1,240.0 L165.3,240.0 L165.3,244.0 L165.5,244.0 L165.5,247.8 L165.7,247.8 L165.7,251.6 L165.9,251.6 + L165.9,255.3 L166.2,255.3 L166.2,259.0 L166.4,259.0 L166.4,262.5 L166.6,262.5 L166.6,266.0 L166.8,266.0 + L166.8,269.4 L167.0,269.4 L167.0,272.7 L167.2,272.7 L167.2,276.0 L167.5,276.0 L167.5,279.2 L167.7,279.2 + L167.7,282.4 L167.9,282.4 L167.9,285.4 L168.1,285.4 L168.1,288.5 L168.3,288.5 L168.3,291.4 L168.5,291.4 + L168.5,294.3 L168.8,294.3 L168.8,297.1 L169.0,297.1 L169.0,299.9 L169.2,299.9 L169.2,302.6 L169.4,302.6 + L169.4,305.3 L169.6,305.3 L169.6,307.9 L169.8,307.9 L169.8,310.5 L170.1,310.5 L170.1,313.0 L170.3,313.0 + L170.3,315.4 L170.5,315.4 L170.5,317.8 L170.7,317.8 L170.7,320.2 L170.9,320.2 L170.9,322.5 L171.1,322.5 + L171.1,324.7 L171.4,324.7 L171.4,327.0 L171.6,327.0 L171.6,329.1 L171.8,329.1 L171.8,331.3 L172.0,331.3 + L172.0,333.3 L172.2,333.3 L172.2,335.4 L172.4,335.4 L172.4,337.4 L172.7,337.4 L172.7,339.3 L172.9,339.3 + L172.9,341.2 L173.1,341.2 L173.1,343.1 L173.3,343.1 L173.3,345.0 L173.5,345.0 L173.5,346.8 L173.8,346.8 + L173.8,348.5 L174.0,348.5 L174.0,350.3 L174.2,350.3 L174.2,351.9 L174.4,351.9 L174.4,353.6 L174.6,353.6 + L174.6,355.2 L174.8,355.2 L174.8,356.8 L175.1,356.8 L175.1,358.4 L175.3,358.4 L175.3,359.9 L175.5,359.9 + L175.5,361.4 L175.7,361.4 L175.7,362.9 L175.9,362.9 L175.9,364.3 L176.1,364.3 L176.1,365.7 L176.4,365.7 + L176.4,367.1 L176.6,367.1 L176.6,368.4 L176.8,368.4 L176.8,369.8 L177.0,369.8 L177.0,371.1 L177.2,371.1 + L177.2,372.3 L177.4,372.3 L177.4,373.6 L177.7,373.6 L177.7,374.8 L177.9,374.8 L177.9,376.0 L178.1,376.0 + L178.1,377.2 L178.3,377.2 L178.3,378.3 L178.5,378.3 L178.5,379.4 L178.7,379.4 L178.7,380.5 L179.0,380.5 + L179.0,381.6 L179.2,381.6 L179.2,382.7 L179.4,382.7 L179.4,383.7 L179.6,383.7 L179.6,384.7 L179.8,384.7 + L179.8,385.7 L180.0,385.7 L180.0,386.7 L180.3,386.7 L180.3,387.6 L180.5,387.6 L180.5,388.5 L180.7,388.5 + L180.7,389.5 L180.9,389.5 L180.9,390.3 L181.1,390.3 L181.1,391.2 L181.4,391.2 L181.4,392.1 L181.6,392.1 + L181.6,392.9 L181.8,392.9 L181.8,393.7 L182.0,393.7 L182.0,394.6 L182.2,394.6 L182.2,395.3 L182.4,395.3 + L182.4,396.1 L182.7,396.1 L182.7,396.9 L182.9,396.9 L182.9,397.6 L183.1,397.6 L183.1,398.3 L183.3,398.3 + L183.3,399.1 L183.5,399.1 L183.5,399.8 L183.7,399.8 L183.7,400.4 L184.0,400.4 L184.0,401.1 L184.2,401.1 + L184.2,401.8 L184.4,401.8 L184.4,394.9 L184.6,394.9 L184.6,388.0 L184.8,388.0 L184.8,381.3 L185.0,381.3 + L185.0,374.7 L185.3,374.7 L185.3,368.2 L185.5,368.2 L185.5,361.9 L185.7,361.9 L185.7,355.6 L185.9,355.6 + L185.9,349.5 L186.1,349.5 L186.1,343.5 L186.3,343.5 L186.3,337.5 L186.6,337.5 L186.6,331.7 L186.8,331.7 + L186.8,326.0 L187.0,326.0 L187.0,320.4 L187.2,320.4 L187.2,314.9 L187.4,314.9 L187.4,309.5 L187.6,309.5 + L187.6,304.2 L187.9,304.2 L187.9,299.0 L188.1,299.0 L188.1,293.9 L188.3,293.9 L188.3,288.9 L188.5,288.9 + L188.5,284.0 L188.7,284.0 L188.7,279.1 L188.9,279.1 L188.9,274.4 L189.2,274.4 L189.2,269.7 L189.4,269.7 + L189.4,265.1 L189.6,265.1 L189.6,260.6 L189.8,260.6 L189.8,256.2 L190.0,256.2 L190.0,251.9 L190.3,251.9 + L190.3,247.6 L190.5,247.6 L190.5,243.4 L190.7,243.4 L190.7,239.3 L190.9,239.3 L190.9,235.3 L191.1,235.3 + L191.1,231.4 L191.3,231.4 L191.3,227.5 L191.6,227.5 L191.6,223.7 L191.8,223.7 L191.8,219.9 L192.0,219.9 + L192.0,216.2 L192.2,216.2 L192.2,212.6 L192.4,212.6 L192.4,209.1 L192.6,209.1 L192.6,205.6 L192.9,205.6 + L192.9,202.2 L193.1,202.2 L193.1,198.8 L193.3,198.8 L193.3,195.5 L193.5,195.5 L193.5,192.3 L193.7,192.3 + L193.7,189.1 L193.9,189.1 L193.9,186.0 L194.2,186.0 L194.2,182.9 L194.4,182.9 L194.4,179.9 L194.6,179.9 + L194.6,177.0 L194.8,177.0 L194.8,174.0 L195.0,174.0 L195.0,171.2 L195.2,171.2 L195.2,168.4 L195.5,168.4 + L195.5,165.7 L195.7,165.7 L195.7,163.0 L195.9,163.0 L195.9,160.3 L196.1,160.3 L196.1,157.7 L196.3,157.7 + L196.3,155.2 L196.5,155.2 L196.5,152.7 L196.8,152.7 L196.8,150.2 L197.0,150.2 L197.0,147.8 L197.2,147.8 + L197.2,145.4 L197.4,145.4 L197.4,143.1 L197.6,143.1 L197.6,140.8 L197.9,140.8 L197.9,138.5 L198.1,138.5 + L198.1,136.3 L198.3,136.3 L198.3,134.2 L198.5,134.2 L198.5,132.0 L198.7,132.0 L198.7,130.0 L198.9,130.0 + L198.9,127.9 L199.2,127.9 L199.2,125.9 L199.4,125.9 L199.4,123.9 L199.6,123.9 L199.6,122.0 L199.8,122.0 + L199.8,120.1 L200.0,120.1 L200.0,118.2 L200.2,118.2 L200.2,116.4 L200.5,116.4 L200.5,114.6 L200.7,114.6 + L200.7,112.8 L200.9,112.8 L200.9,111.0 L201.1,111.0 L201.1,109.3 L201.3,109.3 L201.3,107.7 L201.5,107.7 + L201.5,106.0 L201.8,106.0 L201.8,104.4 L202.0,104.4 L202.0,102.8 L202.2,102.8 L202.2,101.2 L202.4,101.2 + L202.4,99.7 L202.6,99.7 L202.6,98.2 L202.8,98.2 L202.8,96.7 L203.1,96.7 L203.1,95.3 L203.3,95.3 + L203.3,93.9 L203.5,93.9 L203.5,92.5 L203.7,92.5 L203.7,91.1 L203.9,91.1 L203.9,89.8 L204.1,89.8 + L204.1,88.4 L204.4,88.4 L204.4,87.1 L204.6,87.1 L204.6,85.9 L204.8,85.9 L204.8,84.6 L205.0,84.6 + L205.0,83.4 L205.2,83.4 L205.2,82.2 L205.5,82.2 L205.5,81.0 L205.7,81.0 L205.7,79.8 L205.9,79.8 + L205.9,78.7 L206.1,78.7 L206.1,77.6 L206.3,77.6 L206.3,76.5 L206.5,76.5 L206.5,75.4 L206.8,75.4 + L206.8,74.3 L207.0,74.3 L207.0,73.3 L207.2,73.3 L207.2,72.2 L207.4,72.2 L207.4,71.2 L207.6,71.2 + L207.6,70.3 L207.8,70.3 L207.8,69.3 L208.1,69.3 L208.1,68.3 L208.3,68.3 L208.3,67.4 L208.5,67.4 + L208.5,66.5 L208.7,66.5 L208.7,65.6 L208.9,65.6 L208.9,64.7 L209.1,64.7 L209.1,63.8 L209.4,63.8 + L209.4,63.0 L209.6,63.0 L209.6,62.1 L209.8,62.1 L209.8,61.3 L210.0,61.3 L210.0,60.5 L210.2,60.5 + L210.2,59.7 L210.4,59.7 L210.4,67.2 L210.7,67.2 L210.7,74.7 L210.9,74.7 L210.9,82.0 L211.1,82.0 + L211.1,89.2 L211.3,89.2 L211.3,96.2 L211.5,96.2 L211.5,103.1 L211.7,103.1 L211.7,109.8 L212.0,109.8 + L212.0,116.4 L212.2,116.4 L212.2,122.8 L212.4,122.8 L212.4,129.2 L212.6,129.2 L212.6,135.4 L212.8,135.4 + L212.8,141.5 L213.1,141.5 L213.1,147.4 L213.3,147.4 L213.3,153.2 L213.5,153.2 L213.5,158.9 L213.7,158.9 + L213.7,164.5 L213.9,164.5 L213.9,170.0 L214.1,170.0 L214.1,175.4 L214.4,175.4 L214.4,180.6 L214.6,180.6 + L214.6,185.8 L214.8,185.8 L214.8,190.8 L215.0,190.8 L215.0,195.8 L215.2,195.8 L215.2,200.6 L215.4,200.6 + L215.4,205.4 L215.7,205.4 L215.7,210.0 L215.9,210.0 L215.9,214.6 L216.1,214.6 L216.1,219.0 L216.3,219.0 + L216.3,223.4 L216.5,223.4 L216.5,227.7 L216.7,227.7 L216.7,231.9 L217.0,231.9 L217.0,236.0 L217.2,236.0 + L217.2,240.0 L217.4,240.0 L217.4,243.9 L217.6,243.9 L217.6,247.8 L217.8,247.8 L217.8,251.6 L218.0,251.6 + L218.0,255.3 L218.3,255.3 L218.3,258.9 L218.5,258.9 L218.5,262.5 L218.7,262.5 L218.7,266.0 L218.9,266.0 + L218.9,269.4 L219.1,269.4 L219.1,272.7 L219.3,272.7 L219.3,276.0 L219.6,276.0 L219.6,279.2 L219.8,279.2 + L219.8,282.3 L220.0,282.3 L220.0,285.4 L220.2,285.4 L220.2,288.4 L220.4,288.4 L220.4,291.4 L220.6,291.4 + L220.6,294.3 L220.9,294.3 L220.9,297.1 L221.1,297.1 L221.1,299.9 L221.3,299.9 L221.3,302.6 L221.5,302.6 + L221.5,305.3 L221.7,305.3 L221.7,307.9 L222.0,307.9 L222.0,310.4 L222.2,310.4 L222.2,313.0 L222.4,313.0 + L222.4,315.4 L222.6,315.4 L222.6,317.8 L222.8,317.8 L222.8,320.2 L223.0,320.2 L223.0,322.5 L223.3,322.5 + L223.3,324.7 L223.5,324.7 L223.5,326.9 L223.7,326.9 L223.7,329.1 L223.9,329.1 L223.9,331.2 L224.1,331.2 + L224.1,333.3 L224.3,333.3 L224.3,335.4 L224.6,335.4 L224.6,337.4 L224.8,337.4 L224.8,339.3 L225.0,339.3 + L225.0,341.2 L225.2,341.2 L225.2,343.1 L225.4,343.1 L225.4,344.9 L225.6,344.9 L225.6,346.7 L225.9,346.7 + L225.9,348.5 L226.1,348.5 L226.1,350.2 L226.3,350.2 L226.3,351.9 L226.5,351.9 L226.5,353.6 L226.7,353.6 + L226.7,355.2 L226.9,355.2 L226.9,356.8 L227.2,356.8 L227.2,358.4 L227.4,358.4 L227.4,359.9 L227.6,359.9 + L227.6,361.4 L227.8,361.4 L227.8,362.9 L228.0,362.9 L228.0,364.3 L228.2,364.3 L228.2,365.7 L228.5,365.7 + L228.5,367.1 L228.7,367.1 L228.7,368.4 L228.9,368.4 L228.9,369.8 L229.1,369.8 L229.1,371.1 L229.3,371.1 + L229.3,372.3 L229.6,372.3 L229.6,373.6 L229.8,373.6 L229.8,374.8 L230.0,374.8 L230.0,376.0 L230.2,376.0 + L230.2,377.1 L230.4,377.1 L230.4,378.3 L230.6,378.3 L230.6,379.4 L230.9,379.4 L230.9,380.5 L231.1,380.5 + L231.1,381.6 L231.3,381.6 L231.3,382.6 L231.5,382.6 L231.5,383.7 L231.7,383.7 L231.7,384.7 L231.9,384.7 + L231.9,385.7 L232.2,385.7 L232.2,386.7 L232.4,386.7 L232.4,387.6 L232.6,387.6 L232.6,388.5 L232.8,388.5 + L232.8,389.4 L233.0,389.4 L233.0,390.3 L233.2,390.3 L233.2,391.2 L233.5,391.2 L233.5,392.1 L233.7,392.1 + L233.7,392.9 L233.9,392.9 L233.9,393.7 L234.1,393.7 L234.1,394.5 L234.3,394.5 L234.3,395.3 L234.5,395.3 + L234.5,396.1 L234.8,396.1 L234.8,396.9 L235.0,396.9 L235.0,397.6 L235.2,397.6 L235.2,398.3 L235.4,398.3 + L235.4,399.1 L235.6,399.1 L235.6,399.8 L235.8,399.8 L235.8,400.4 L236.1,400.4 L236.1,401.1 L236.3,401.1 + L236.3,401.8 L236.5,401.8 L236.5,394.9 L236.7,394.9 L236.7,388.1 L236.9,388.1 L236.9,381.3 L237.2,381.3 + L237.2,374.7 L237.4,374.7 L237.4,368.2 L237.6,368.2 L237.6,361.9 L237.8,361.9 L237.8,355.6 L238.0,355.6 + L238.0,349.5 L238.2,349.5 L238.2,343.5 L238.5,343.5 L238.5,337.6 L238.7,337.6 L238.7,331.7 L238.9,331.7 + L238.9,326.0 L239.1,326.0 L239.1,320.4 L239.3,320.4 L239.3,314.9 L239.5,314.9 L239.5,309.5 L239.8,309.5 + L239.8,304.2 L240.0,304.2 L240.0,299.0 L240.2,299.0 L240.2,293.9 L240.4,293.9 L240.4,288.9 L240.6,288.9 + L240.6,284.0 L240.8,284.0 L240.8,279.1 L241.1,279.1 L241.1,274.4 L241.3,274.4 L241.3,269.7 L241.5,269.7 + L241.5,265.1 L241.7,265.1 L241.7,260.7 L241.9,260.7 L241.9,256.2 L242.1,256.2 L242.1,251.9 L242.4,251.9 + L242.4,247.6 L242.6,247.6 L242.6,243.5 L242.8,243.5 L242.8,239.4 L243.0,239.4 L243.0,235.3 L243.2,235.3 + L243.2,231.4 L243.4,231.4 L243.4,227.5 L243.7,227.5 L243.7,223.7 L243.9,223.7 L243.9,219.9 L244.1,219.9 + L244.1,216.2 L244.3,216.2 L244.3,212.6 L244.5,212.6 L244.5,209.1 L244.7,209.1 L244.7,205.6 L245.0,205.6 + L245.0,202.2 L245.2,202.2 L245.2,198.8 L245.4,198.8 L245.4,195.5 L245.6,195.5 L245.6,192.3 L245.8,192.3 + L245.8,189.1 L246.1,189.1 L246.1,186.0 L246.3,186.0 L246.3,182.9 L246.5,182.9 L246.5,179.9 L246.7,179.9 + L246.7,177.0 L246.9,177.0 L246.9,174.1 L247.1,174.1 L247.1,171.2 L247.4,171.2 L247.4,168.4 L247.6,168.4 + L247.6,165.7 L247.8,165.7 L247.8,163.0 L248.0,163.0 L248.0,160.3 L248.2,160.3 L248.2,157.7 L248.4,157.7 + L248.4,155.2 L248.7,155.2 L248.7,152.7 L248.9,152.7 L248.9,150.2 L249.1,150.2 L249.1,147.8 L249.3,147.8 + L249.3,145.4 L249.5,145.4 L249.5,143.1 L249.7,143.1 L249.7,140.8 L250.0,140.8 L250.0,138.5 L250.2,138.5 + L250.2,136.3 L250.4,136.3 L250.4,134.2 L250.6,134.2 L250.6,132.0 L250.8,132.0 L250.8,130.0 L251.0,130.0 + L251.0,127.9 L251.3,127.9 L251.3,125.9 L251.5,125.9 L251.5,123.9 L251.7,123.9 L251.7,122.0 L251.9,122.0 + L251.9,120.1 L252.1,120.1 L252.1,118.2 L252.3,118.2 L252.3,116.4 L252.6,116.4 L252.6,114.6 L252.8,114.6 + L252.8,112.8 L253.0,112.8 L253.0,111.1 L253.2,111.1 L253.2,109.3 L253.4,109.3 L253.4,107.7 L253.7,107.7 + L253.7,106.0 L253.9,106.0 L253.9,104.4 L254.1,104.4 L254.1,102.8 L254.3,102.8 L254.3,101.3 L254.5,101.3 + L254.5,99.7 L254.7,99.7 L254.7,98.2 L255.0,98.2 L255.0,96.7 L255.2,96.7 L255.2,95.3 L255.4,95.3 + L255.4,93.9 L255.6,93.9 L255.6,92.5 L255.8,92.5 L255.8,91.1 L256.0,91.1 L256.0,89.8 L256.3,89.8 + L256.3,88.4 L256.5,88.4 L256.5,87.1 L256.7,87.1 L256.7,85.9 L256.9,85.9 L256.9,84.6 L257.1,84.6 + L257.1,83.4 L257.3,83.4 L257.3,82.2 L257.6,82.2 L257.6,81.0 L257.8,81.0 L257.8,79.8 L258.0,79.8 + L258.0,78.7 L258.2,78.7 L258.2,77.6 L258.4,77.6 L258.4,76.5 L258.6,76.5 L258.6,75.4 L258.9,75.4 + L258.9,74.3 L259.1,74.3 L259.1,73.3 L259.3,73.3 L259.3,72.2 L259.5,72.2 L259.5,71.2 L259.7,71.2 + L259.7,70.3 L259.9,70.3 L259.9,69.3 L260.2,69.3 L260.2,68.3 L260.4,68.3 L260.4,67.4 L260.6,67.4 + L260.6,66.5 L260.8,66.5 L260.8,65.6 L261.0,65.6 L261.0,64.7 L261.3,64.7 L261.3,63.8 L261.5,63.8 + L261.5,63.0 L261.7,63.0 L261.7,62.1 L261.9,62.1 L261.9,61.3 L262.1,61.3 L262.1,60.5 L262.3,60.5 + L262.3,59.7 L262.6,59.7 L262.6,67.2 L262.8,67.2 L262.8,74.7 L263.0,74.7 L263.0,82.0 L263.2,82.0 + L263.2,89.1 L263.4,89.1 L263.4,96.2 L263.6,96.2 L263.6,103.0 L263.9,103.0 L263.9,109.8 L264.1,109.8 + L264.1,116.4 L264.3,116.4 L264.3,122.8 L264.5,122.8 L264.5,129.2 L264.7,129.2 L264.7,135.4 L264.9,135.4 + L264.9,141.4 L265.2,141.4 L265.2,147.4 L265.4,147.4 L265.4,153.2 L265.6,153.2 L265.6,158.9 L265.8,158.9 + L265.8,164.5 L266.0,164.5 L266.0,170.0 L266.2,170.0 L266.2,175.4 L266.5,175.4 L266.5,180.6 L266.7,180.6 + L266.7,185.8 L266.9,185.8 L266.9,190.8 L267.1,190.8 L267.1,195.8 L267.3,195.8 L267.3,200.6 L267.5,200.6 + L267.5,205.4 L267.8,205.4 L267.8,210.0 L268.0,210.0 L268.0,214.6 L268.2,214.6 L268.2,219.0 L268.4,219.0 + L268.4,223.4 L268.6,223.4 L268.6,227.7 L268.9,227.7 L268.9,231.9 L269.1,231.9 L269.1,236.0 L269.3,236.0 + L269.3,240.0 L269.5,240.0 L269.5,243.9 L269.7,243.9 L269.7,247.8 L269.9,247.8 L269.9,251.6 L270.2,251.6 + L270.2,255.3 L270.4,255.3 L270.4,258.9 L270.6,258.9 L270.6,262.5 L270.8,262.5 L270.8,265.9 L271.0,265.9 + L271.0,269.4 L271.2,269.4 L271.2,272.7 L271.5,272.7 L271.5,276.0 L271.7,276.0 L271.7,279.2 L271.9,279.2 + L271.9,282.3 L272.1,282.3 L272.1,285.4 L272.3,285.4 L272.3,288.4 L272.5,288.4 L272.5,291.4 L272.8,291.4 + L272.8,294.3 L273.0,294.3 L273.0,297.1 L273.2,297.1 L273.2,299.9 L273.4,299.9 L273.4,302.6 L273.6,302.6 + L273.6,305.3 L273.8,305.3 L273.8,307.9 L274.1,307.9 L274.1,310.4 L274.3,310.4 L274.3,312.9 L274.5,312.9 + L274.5,315.4 L274.7,315.4 L274.7,317.8 L274.9,317.8 L274.9,320.2 L275.1,320.2 L275.1,322.5 L275.4,322.5 + L275.4,324.7 L275.6,324.7 L275.6,326.9 L275.8,326.9 L275.8,329.1 L276.0,329.1 L276.0,331.2 L276.2,331.2 + L276.2,333.3 L276.4,333.3 L276.4,335.3 L276.7,335.3 L276.7,337.3 L276.9,337.3 L276.9,339.3 L277.1,339.3 + L277.1,341.2 L277.3,341.2 L277.3,343.1 L277.5,343.1 L277.5,344.9 L277.8,344.9 L277.8,346.7 L278.0,346.7 + L278.0,348.5 L278.2,348.5 L278.2,350.2 L278.4,350.2 L278.4,351.9 L278.6,351.9 L278.6,353.6 L278.8,353.6 + L278.8,355.2 L279.1,355.2 L279.1,356.8 L279.3,356.8 L279.3,358.4 L279.5,358.4 L279.5,359.9 L279.7,359.9 + L279.7,361.4 L279.9,361.4 L279.9,362.9 L280.1,362.9 L280.1,364.3 L280.4,364.3 L280.4,365.7 L280.6,365.7 + L280.6,367.1 L280.8,367.1 L280.8,368.4 L281.0,368.4 L281.0,369.8 L281.2,369.8 L281.2,371.0 L281.4,371.0 + L281.4,372.3 L281.7,372.3 L281.7,373.6 L281.9,373.6 L281.9,374.8 L282.1,374.8 L282.1,376.0 L282.3,376.0 + L282.3,377.1 L282.5,377.1 L282.5,378.3 L282.7,378.3 L282.7,379.4 L283.0,379.4 L283.0,380.5 L283.2,380.5 + L283.2,381.6 L283.4,381.6 L283.4,382.6 L283.6,382.6 L283.6,383.7 L283.8,383.7 L283.8,384.7 L284.0,384.7 + L284.0,385.7 L284.3,385.7 L284.3,386.6 L284.5,386.6 L284.5,387.6 L284.7,387.6 L284.7,388.5 L284.9,388.5 + L284.9,389.4 L285.1,389.4 L285.1,390.3 L285.4,390.3 L285.4,391.2 L285.6,391.2 L285.6,392.1 L285.8,392.1 + L285.8,392.9 L286.0,392.9 L286.0,393.7 L286.2,393.7 L286.2,394.5 L286.4,394.5 L286.4,395.3 L286.7,395.3 + L286.7,396.1 L286.9,396.1 L286.9,396.9 L287.1,396.9 L287.1,397.6 L287.3,397.6 L287.3,398.3 L287.5,398.3 + L287.5,399.1 L287.7,399.1 L287.7,399.8 L288.0,399.8 L288.0,400.4 L288.2,400.4 L288.2,401.1 L288.4,401.1 + L288.4,401.8 L288.6,401.8 L288.6,394.9 L288.8,394.9 L288.8,388.1 L289.0,388.1 L289.0,381.4 L289.3,381.4 + L289.3,374.8 L289.5,374.8 L289.5,368.3 L289.7,368.3 L289.7,361.9 L289.9,361.9 L289.9,355.7 L290.1,355.7 + L290.1,349.5 L290.3,349.5 L290.3,343.5 L290.6,343.5 L290.6,337.6 L290.8,337.6 L290.8,331.8 L291.0,331.8 + L291.0,326.1 L291.2,326.1 L291.2,320.5 L291.4,320.5 L291.4,315.0 L291.6,315.0 L291.6,309.6 L291.9,309.6 + L291.9,304.3 L292.1,304.3 L292.1,299.1 L292.3,299.1 L292.3,294.0 L292.5,294.0 L292.5,288.9 L292.7,288.9 + L292.7,284.0 L293.0,284.0 L293.0,279.2 L293.2,279.2 L293.2,274.4 L293.4,274.4 L293.4,269.7 L293.6,269.7 + L293.6,265.2 L293.8,265.2 L293.8,260.7 L294.0,260.7 L294.0,256.3 L294.3,256.3 L294.3,251.9 L294.5,251.9 + L294.5,247.7 L294.7,247.7 L294.7,243.5 L294.9,243.5 L294.9,239.4 L295.1,239.4 L295.1,235.3 L295.3,235.3 + L295.3,231.4 L295.6,231.4 L295.6,227.5 L295.8,227.5 L295.8,223.7 L296.0,223.7 L296.0,219.9 L296.2,219.9 + L296.2,216.3 L296.4,216.3 L296.4,212.6 L296.6,212.6 L296.6,209.1 L296.9,209.1 L296.9,205.6 L297.1,205.6 + L297.1,202.2 L297.3,202.2 L297.3,198.8 L297.5,198.8 L297.5,195.5 L297.7,195.5 L297.7,192.3 L297.9,192.3 + L297.9,189.1 L298.2,189.1 L298.2,186.0 L298.4,186.0 L298.4,182.9 L298.6,182.9 L298.6,179.9 L298.8,179.9 + L298.8,177.0 L299.0,177.0 L299.0,174.1 L299.2,174.1 L299.2,171.2 L299.5,171.2 L299.5,168.4 L299.7,168.4 + L299.7,165.7 L299.9,165.7 L299.9,163.0 L300.1,163.0 L300.1,160.3 L300.3,160.3 L300.3,157.7 L300.6,157.7 + L300.6,155.2 L300.8,155.2 L300.8,152.7 L301.0,152.7 L301.0,150.2 L301.2,150.2 L301.2,147.8 L301.4,147.8 + L301.4,145.4 L301.6,145.4 L301.6,143.1 L301.9,143.1 L301.9,140.8 L302.1,140.8 L302.1,138.6 L302.3,138.6 + L302.3,136.4 L302.5,136.4 L302.5,134.2 L302.7,134.2 L302.7,132.1 L302.9,132.1 L302.9,130.0 L303.2,130.0 + L303.2,127.9 L303.4,127.9 L303.4,125.9 L303.6,125.9 L303.6,123.9 L303.8,123.9 L303.8,122.0 L304.0,122.0 + L304.0,120.1 L304.2,120.1 L304.2,118.2 L304.5,118.2 L304.5,116.4 L304.7,116.4 L304.7,114.6 L304.9,114.6 + L304.9,112.8 L305.1,112.8 L305.1,111.1 L305.3,111.1 L305.3,109.3 L305.5,109.3 L305.5,107.7 L305.8,107.7 + L305.8,106.0 L306.0,106.0 L306.0,104.4 L306.2,104.4 L306.2,102.8 L306.4,102.8 L306.4,101.3 L306.6,101.3 + L306.6,99.7 L306.8,99.7 L306.8,98.2 L307.1,98.2 L307.1,96.8 L307.3,96.8 L307.3,95.3 L307.5,95.3 + L307.5,93.9 L307.7,93.9 L307.7,92.5 L307.9,92.5 L307.9,91.1 L308.1,91.1 L308.1,89.8 L308.4,89.8 + L308.4,88.4 L308.6,88.4 L308.6,87.1 L308.8,87.1 L308.8,85.9 L309.0,85.9 L309.0,84.6 L309.2,84.6 + L309.2,83.4 L309.5,83.4 L309.5,82.2 L309.7,82.2 L309.7,81.0 L309.9,81.0 L309.9,79.8 L310.1,79.8 + L310.1,78.7 L310.3,78.7 L310.3,77.6 L310.5,77.6 L310.5,76.5 L310.8,76.5 L310.8,75.4 L311.0,75.4 + L311.0,74.3 L311.2,74.3 L311.2,73.3 L311.4,73.3 L311.4,72.3 L311.6,72.3 L311.6,71.2 L311.8,71.2 + L311.8,70.3 L312.1,70.3 L312.1,69.3 L312.3,69.3 L312.3,68.3 L312.5,68.3 L312.5,67.4 L312.7,67.4 + L312.7,66.5 L312.9,66.5 L312.9,65.6 L313.1,65.6 L313.1,64.7 L313.4,64.7 L313.4,63.8 L313.6,63.8 + L313.6,63.0 L313.8,63.0 L313.8,62.1 L314.0,62.1 L314.0,61.3 L314.2,61.3 L314.2,60.5 L314.4,60.5 + L314.4,59.7 L314.7,59.7 L314.7,67.2 L314.9,67.2 L314.9,74.6 L315.1,74.6 L315.1,81.9 L315.3,81.9 + L315.3,89.1 L315.5,89.1 L315.5,96.1 L315.7,96.1 L315.7,103.0 L316.0,103.0 L316.0,109.7 L316.2,109.7 + L316.2,116.3 L316.4,116.3 L316.4,122.8 L316.6,122.8 L316.6,129.1 L316.8,129.1 L316.8,135.3 L317.1,135.3 + L317.1,141.4 L317.3,141.4 L317.3,147.4 L317.5,147.4 L317.5,153.2 L317.7,153.2 L317.7,158.9 L317.9,158.9 + L317.9,164.5 L318.1,164.5 L318.1,170.0 L318.4,170.0 L318.4,175.3 L318.6,175.3 L318.6,180.6 L318.8,180.6 + L318.8,185.8 L319.0,185.8 L319.0,190.8 L319.2,190.8 L319.2,195.7 L319.4,195.7 L319.4,200.6 L319.7,200.6 + L319.7,205.3 L319.9,205.3 L319.9,210.0 L320.1,210.0 L320.1,214.5 L320.3,214.5 L320.3,219.0 L320.5,219.0 + L320.5,223.4 L320.7,223.4 L320.7,227.6 L321.0,227.6 L321.0,231.8 L321.2,231.8 L321.2,235.9 L321.4,235.9 + L321.4,240.0 L321.6,240.0 L321.6,243.9 L321.8,243.9 L321.8,247.8 L322.0,247.8 L322.0,251.6 L322.3,251.6 + L322.3,255.3 L322.5,255.3 L322.5,258.9 L322.7,258.9 L322.7,262.5 L322.9,262.5 L322.9,265.9 L323.1,265.9 + L323.1,269.3 L323.3,269.3 L323.3,272.7 L323.6,272.7 L323.6,276.0 L323.8,276.0 L323.8,279.2 L324.0,279.2 + L324.0,282.3 L324.2,282.3 L324.2,285.4 L324.4,285.4 L324.4,288.4 L324.7,288.4 L324.7,291.4 L324.9,291.4 + L324.9,294.3 L325.1,294.3 L325.1,297.1 L325.3,297.1 L325.3,299.9 L325.5,299.9 L325.5,302.6 L325.7,302.6 + L325.7,305.3 L326.0,305.3 L326.0,307.9 L326.2,307.9 L326.2,310.4 L326.4,310.4 L326.4,312.9 L326.6,312.9 + L326.6,315.4 L326.8,315.4 L326.8,317.8 L327.0,317.8 L327.0,320.1 L327.3,320.1 L327.3,322.5 L327.5,322.5 + L327.5,324.7 L327.7,324.7 L327.7,326.9 L327.9,326.9 L327.9,329.1 L328.1,329.1 L328.1,331.2 L328.3,331.2 + L328.3,333.3 L328.6,333.3 L328.6,335.3 L328.8,335.3 L328.8,337.3 L329.0,337.3 L329.0,339.3 L329.2,339.3 + L329.2,341.2 L329.4,341.2 L329.4,343.1 L329.6,343.1 L329.6,344.9 L329.9,344.9 L329.9,346.7 L330.1,346.7 + L330.1,348.5 L330.3,348.5 L330.3,350.2 L330.5,350.2 L330.5,351.9 L330.7,351.9 L330.7,353.6 L330.9,353.6 + L330.9,355.2 L331.2,355.2 L331.2,356.8 L331.4,356.8 L331.4,358.4 L331.6,358.4 L331.6,359.9 L331.8,359.9 + L331.8,361.4 L332.0,361.4 L332.0,362.9 L332.2,362.9 L332.2,364.3 L332.5,364.3 L332.5,365.7 L332.7,365.7 + L332.7,367.1 L332.9,367.1 L332.9,368.4 L333.1,368.4 L333.1,369.7 L333.3,369.7 L333.3,371.0 L333.6,371.0 + L333.6,372.3 L333.8,372.3 L333.8,373.6 L334.0,373.6 L334.0,374.8 L334.2,374.8 L334.2,376.0 L334.4,376.0 + L334.4,377.1 L334.6,377.1 L334.6,378.3 L334.9,378.3 L334.9,379.4 L335.1,379.4 L335.1,380.5 L335.3,380.5 + L335.3,381.6 L335.5,381.6 L335.5,382.6 L335.7,382.6 L335.7,383.7 L335.9,383.7 L335.9,384.7 L336.2,384.7 + L336.2,385.7 L336.4,385.7 L336.4,386.6 L336.6,386.6 L336.6,387.6 L336.8,387.6 L336.8,388.5 L337.0,388.5 + L337.0,389.4 L337.2,389.4 L337.2,390.3 L337.5,390.3 L337.5,391.2 L337.7,391.2 L337.7,392.1 L337.9,392.1 + L337.9,392.9 L338.1,392.9 L338.1,393.7 L338.3,393.7 L338.3,394.5 L338.5,394.5 L338.5,395.3 L338.8,395.3 + L338.8,396.1 L339.0,396.1 L339.0,396.9 L339.2,396.9 L339.2,397.6 L339.4,397.6 L339.4,398.3 L339.6,398.3 + L339.6,399.1 L339.8,399.1 L339.8,399.7 L340.1,399.7 L340.1,400.4 L340.3,400.4 L340.3,401.1 L340.5,401.1 + L340.5,401.8 L340.7,401.8 L340.7,394.9 L340.9,394.9 L340.9,388.1 L341.2,388.1 L341.2,381.4 L341.4,381.4 + L341.4,374.8 L341.6,374.8 L341.6,368.3 L341.8,368.3 L341.8,361.9 L342.0,361.9 L342.0,355.7 L342.2,355.7 + L342.2,349.5 L342.5,349.5 L342.5,343.5 L342.7,343.5 L342.7,337.6 L342.9,337.6 L342.9,331.8 L343.1,331.8 + L343.1,326.1 L343.3,326.1 L343.3,320.5 L343.5,320.5 L343.5,315.0 L343.8,315.0 L343.8,309.6 L344.0,309.6 + L344.0,304.3 L344.2,304.3 L344.2,299.1 L344.4,299.1 L344.4,294.0 L344.6,294.0 L344.6,289.0 L344.8,289.0 + L344.8,284.0 L345.1,284.0 L345.1,279.2 L345.3,279.2 L345.3,274.4 L345.5,274.4 L345.5,269.8 L345.7,269.8 + L345.7,265.2 L345.9,265.2 L345.9,260.7 L346.1,260.7 L346.1,256.3 L346.4,256.3 L346.4,251.9 L346.6,251.9 + L346.6,247.7 L346.8,247.7 L346.8,243.5 L347.0,243.5 L347.0,239.4 L347.2,239.4 L347.2,235.4 L347.4,235.4 + L347.4,231.4 L347.7,231.4 L347.7,227.5 L347.9,227.5 L347.9,223.7 L348.1,223.7 L348.1,219.9 L348.3,219.9 + L348.3,216.3 L348.5,216.3 L348.5,212.7 L348.8,212.7 L348.8,209.1 L349.0,209.1 L349.0,205.6 L349.2,205.6 + L349.2,202.2 L349.4,202.2 L349.4,198.8 L349.6,198.8 L349.6,195.6 L349.8,195.6 L349.8,192.3 L350.1,192.3 + L350.1,189.1 L350.3,189.1 L350.3,186.0 L350.5,186.0 L350.5,182.9 L350.7,182.9 L350.7,179.9 L350.9,179.9 + L350.9,177.0 L351.1,177.0 L351.1,174.1 L351.4,174.1 L351.4,171.2 L351.6,171.2 L351.6,168.4 L351.8,168.4 + L351.8,165.7 L352.0,165.7 L352.0,163.0 L352.2,163.0 L352.2,160.3 L352.4,160.3 L352.4,157.7 L352.7,157.7 + L352.7,155.2 L352.9,155.2 L352.9,152.7 L353.1,152.7 L353.1,150.2 L353.3,150.2 L353.3,147.8 L353.5,147.8 + L353.5,145.4 L353.7,145.4 L353.7,143.1 L354.0,143.1 L354.0,140.8 L354.2,140.8 L354.2,138.6 L354.4,138.6 + L354.4,136.4 L354.6,136.4 L354.6,134.2 L354.8,134.2 L354.8,132.1 L355.0,132.1 L355.0,130.0 L355.3,130.0 + L355.3,127.9 L355.5,127.9 L355.5,125.9 L355.7,125.9 L355.7,123.9 L355.9,123.9 L355.9,122.0 L356.1,122.0 + L356.1,120.1 L356.4,120.1 L356.4,118.2 L356.6,118.2 L356.6,116.4 L356.8,116.4 L356.8,114.6 L357.0,114.6 + L357.0,112.8 L357.2,112.8 L357.2,111.1 L357.4,111.1 L357.4,109.4 L357.7,109.4 L357.7,107.7 L357.9,107.7 + L357.9,106.0 L358.1,106.0 L358.1,104.4 L358.3,104.4 L358.3,102.8 L358.5,102.8 L358.5,101.3 L358.7,101.3 + L358.7,99.7 L359.0,99.7 L359.0,98.2 L359.2,98.2 L359.2,96.8 L359.4,96.8 L359.4,95.3 L359.6,95.3 + L359.6,93.9 L359.8,93.9 L359.8,92.5 L360.0,92.5 L360.0,91.1 L360.3,91.1 L360.3,89.8 L360.5,89.8 + L360.5,88.4 L360.7,88.4 L360.7,87.1 L360.9,87.1 L360.9,85.9 L361.1,85.9 L361.1,84.6 L361.3,84.6 + L361.3,83.4 L361.6,83.4 L361.6,82.2 L361.8,82.2 L361.8,81.0 L362.0,81.0 L362.0,79.8 L362.2,79.8 + L362.2,78.7 L362.4,78.7 L362.4,77.6 L362.6,77.6 L362.6,76.5 L362.9,76.5 L362.9,75.4 L363.1,75.4 + L363.1,74.3 L363.3,74.3 L363.3,73.3 L363.5,73.3 L363.5,72.3 L363.7,72.3 L363.7,71.2 L363.9,71.2 + L363.9,70.3 L364.2,70.3 L364.2,69.3 L364.4,69.3 L364.4,68.3 L364.6,68.3 L364.6,67.4 L364.8,67.4 + L364.8,66.5 L365.0,66.5 L365.0,65.6 L365.3,65.6 L365.3,64.7 L365.5,64.7 L365.5,63.8 L365.7,63.8 + L365.7,63.0 L365.9,63.0 L365.9,62.1 L366.1,62.1 L366.1,61.3 L366.3,61.3 L366.3,60.5 L366.6,60.5 + L366.6,59.7 L366.8,59.7 L366.8,67.1 L367.0,67.1 L367.0,74.6 L367.2,74.6 L367.2,81.9 L367.4,81.9 + L367.4,89.1 L367.6,89.1 L367.6,96.1 L367.9,96.1 L367.9,103.0 L368.1,103.0 L368.1,109.7 L368.3,109.7 + L368.3,116.3 L368.5,116.3 L368.5,122.8 L368.7,122.8 L368.7,129.1 L368.9,129.1 L368.9,135.3 L369.2,135.3 + L369.2,141.4 L369.4,141.4 L369.4,147.3 L369.6,147.3 L369.6,153.2 L369.8,153.2 L369.8,158.9 L370.0,158.9 + L370.0,164.5 L370.2,164.5 L370.2,170.0 L370.5,170.0 L370.5,175.3 L370.7,175.3 L370.7,180.6 L370.9,180.6 + L370.9,185.7 L371.1,185.7 L371.1,190.8 L371.3,190.8 L371.3,195.7 L371.5,195.7 L371.5,200.6 L371.8,200.6 + L371.8,205.3 L372.0,205.3 L372.0,210.0 L372.2,210.0 L372.2,214.5 L372.4,214.5 L372.4,219.0 L372.6,219.0 + L372.6,223.4 L372.9,223.4 L372.9,227.6 L373.1,227.6 L373.1,231.8 L373.3,231.8 L373.3,235.9 L373.5,235.9 + L373.5,240.0 L373.7,240.0 L373.7,243.9 L373.9,243.9 L373.9,247.8 L374.2,247.8 L374.2,251.5 L374.4,251.5 + L374.4,255.3 L374.6,255.3 L374.6,258.9 L374.8,258.9 L374.8,262.4 L375.0,262.4 L375.0,265.9 L375.2,265.9 + L375.2,269.3 L375.5,269.3 L375.5,272.7 L375.7,272.7 L375.7,276.0 L375.9,276.0 L375.9,279.2 L376.1,279.2 + L376.1,282.3 L376.3,282.3 L376.3,285.4 L376.5,285.4 L376.5,288.4 L376.8,288.4 L376.8,291.4 L377.0,291.4 + L377.0,294.2 L377.2,294.2 L377.2,297.1 L377.4,297.1 L377.4,299.9 L377.6,299.9 L377.6,302.6 L377.8,302.6 + L377.8,305.2 L378.1,305.2 L378.1,307.9 L378.3,307.9 L378.3,310.4 L378.5,310.4 L378.5,312.9 L378.7,312.9 + L378.7,315.4 L378.9,315.4 L378.9,317.8 L379.1,317.8 L379.1,320.1 L379.4,320.1 L379.4,322.4 L379.6,322.4 + L379.6,324.7 L379.8,324.7 L379.8,326.9 L380.0,326.9 L380.0,329.1 L380.2,329.1 L380.2,331.2 L380.5,331.2 + L380.5,333.3 L380.7,333.3 L380.7,335.3 L380.9,335.3 L380.9,337.3 L381.1,337.3 L381.1,339.3 L381.3,339.3 + L381.3,341.2 L381.5,341.2 L381.5,343.1 L381.8,343.1 L381.8,344.9 L382.0,344.9 L382.0,346.7 L382.2,346.7 + L382.2,348.5 L382.4,348.5 L382.4,350.2 L382.6,350.2 L382.6,351.9 L382.8,351.9 L382.8,353.6 L383.1,353.6 + L383.1,355.2 L383.3,355.2 L383.3,356.8 L383.5,356.8 L383.5,358.4 L383.7,358.4 L383.7,359.9 L383.9,359.9 + L383.9,361.4 L384.1,361.4 L384.1,362.8 L384.4,362.8 L384.4,364.3 L384.6,364.3 L384.6,365.7 L384.8,365.7 + L384.8,367.1 L385.0,367.1 L385.0,368.4 L385.2,368.4 L385.2,369.7 L385.4,369.7 L385.4,371.0 L385.7,371.0 + L385.7,372.3 L385.9,372.3 L385.9,373.6 L386.1,373.6 L386.1,374.8 L386.3,374.8 L386.3,376.0 L386.5,376.0 + L386.5,377.1 L386.7,377.1 L386.7,378.3 L387.0,378.3 L387.0,379.4 L387.2,379.4 L387.2,380.5 L387.4,380.5 + L387.4,381.6 L387.6,381.6 L387.6,382.6 L387.8,382.6 L387.8,383.7 L388.1,383.7 L388.1,384.7 L388.3,384.7 + L388.3,385.7 L388.5,385.7 L388.5,386.6 L388.7,386.6 L388.7,387.6 L388.9,387.6 L388.9,388.5 L389.1,388.5 + L389.1,389.4 L389.4,389.4 L389.4,390.3 L389.6,390.3 L389.6,391.2 L389.8,391.2 L389.8,392.1 L390.0,392.1 + L390.0,392.9 L390.2,392.9 L390.2,393.7 L390.4,393.7 L390.4,394.5 L390.7,394.5 L390.7,395.3 L390.9,395.3 + L390.9,396.1 L391.1,396.1 L391.1,396.9 L391.3,396.9 L391.3,397.6 L391.5,397.6 L391.5,398.3 L391.7,398.3 + L391.7,399.0 L392.0,399.0 L392.0,399.7 L392.2,399.7 L392.2,400.4 L392.4,400.4 L392.4,401.1 L392.6,401.1 + L392.6,401.8 L392.8,401.8 L392.8,395.0 L393.0,395.0 L393.0,388.1 L393.3,388.1 L393.3,381.4 L393.5,381.4 + L393.5,374.8 L393.7,374.8 L393.7,368.3 L393.9,368.3 L393.9,362.0 L394.1,362.0 L394.1,355.7 L394.3,355.7 + L394.3,349.6 L394.6,349.6 L394.6,343.5 L394.8,343.5 L394.8,337.6 L395.0,337.6 L395.0,331.8 L395.2,331.8 + L395.2,326.1 L395.4,326.1 L395.4,320.5 L395.6,320.5 L395.6,315.0 L395.9,315.0 L395.9,309.6 L396.1,309.6 + L396.1,304.3 L396.3,304.3 L396.3,299.1 L396.5,299.1 L396.5,294.0 L396.7,294.0 L396.7,289.0 L397.0,289.0 + L397.0,284.0 L397.2,284.0 L397.2,279.2 L397.4,279.2 L397.4,274.4 L397.6,274.4 L397.6,269.8 L397.8,269.8 + L397.8,265.2 L398.0,265.2 L398.0,260.7 L398.3,260.7 L398.3,256.3 L398.5,256.3 L398.5,251.9 L398.7,251.9 + L398.7,247.7 L398.9,247.7 L398.9,243.5 L399.1,243.5 L399.1,239.4 L399.3,239.4 L399.3,235.4 L399.6,235.4 + L399.6,231.4 L399.8,231.4 L399.8,227.5 L400.0,227.5 L400.0,223.7 L400.2,223.7 L400.2,220.0 L400.4,220.0 + L400.4,216.3 L400.6,216.3 L400.6,212.7 L400.9,212.7 L400.9,209.1 L401.1,209.1 L401.1,205.6 L401.3,205.6 + L401.3,202.2 L401.5,202.2 L401.5,198.9 L401.7,198.9 L401.7,195.6 L401.9,195.6 L401.9,192.3 L402.2,192.3 + L402.2,189.1 L402.4,189.1 L402.4,186.0 L402.6,186.0 L402.6,183.0 L402.8,183.0 L402.8,179.9 L403.0,179.9 + L403.0,177.0 L403.2,177.0 L403.2,174.1 L403.5,174.1 L403.5,171.2 L403.7,171.2 L403.7,168.4 L403.9,168.4 + L403.9,165.7 L404.1,165.7 L404.1,163.0 L404.3,163.0 L404.3,160.4 L404.6,160.4 L404.6,157.8 L404.8,157.8 + L404.8,155.2 L405.0,155.2 L405.0,152.7 L405.2,152.7 L405.2,150.2 L405.4,150.2 L405.4,147.8 L405.6,147.8 + L405.6,145.4 L405.9,145.4 L405.9,143.1 L406.1,143.1 L406.1,140.8 L406.3,140.8 L406.3,138.6 L406.5,138.6 + L406.5,136.4 L406.7,136.4 L406.7,134.2 L406.9,134.2 L406.9,132.1 L407.2,132.1 L407.2,130.0 L407.4,130.0 + L407.4,127.9 L407.6,127.9 L407.6,125.9 L407.8,125.9 L407.8,123.9 L408.0,123.9 L408.0,122.0 L408.2,122.0 + L408.2,120.1 L408.5,120.1 L408.5,118.2 L408.7,118.2 L408.7,116.4 L408.9,116.4 L408.9,114.6 L409.1,114.6 + L409.1,112.8 L409.3,112.8 L409.3,111.1 L409.5,111.1 L409.5,109.4 L409.8,109.4 L409.8,107.7 L410.0,107.7 + L410.0,106.0 L410.2,106.0 L410.2,104.4 L410.4,104.4 L410.4,102.8 L410.6,102.8 L410.6,101.3 L410.8,101.3 + L410.8,99.7 L411.1,99.7 L411.1,98.2 L411.3,98.2 L411.3,96.8 L411.5,96.8 L411.5,95.3 L411.7,95.3 + L411.7,93.9 L411.9,93.9 L411.9,92.5 L412.2,92.5 L412.2,91.1 L412.4,91.1 L412.4,89.8 L412.6,89.8 + L412.6,88.5 L412.8,88.5 L412.8,87.2 L413.0,87.2 L413.0,85.9 L413.2,85.9 L413.2,84.6 L413.5,84.6 + L413.5,83.4 L413.7,83.4 L413.7,82.2 L413.9,82.2 L413.9,81.0 L414.1,81.0 L414.1,79.8 L414.3,79.8 + L414.3,78.7 L414.5,78.7 L414.5,77.6 L414.8,77.6 L414.8,76.5 L415.0,76.5 L415.0,75.4 L415.2,75.4 + L415.2,74.3 L415.4,74.3 L415.4,73.3 L415.6,73.3 L415.6,72.3 L415.8,72.3 L415.8,71.3 L416.1,71.3 + L416.1,70.3 L416.3,70.3 L416.3,69.3 L416.5,69.3 L416.5,68.3 L416.7,68.3 L416.7,67.4 L416.9,67.4 + L416.9,66.5 L417.1,66.5 L417.1,65.6 L417.4,65.6 L417.4,64.7 L417.6,64.7 L417.6,63.8 L417.8,63.8 + L417.8,63.0 L418.0,63.0 L418.0,62.1 L418.2,62.1 L418.2,61.3 L418.4,61.3 L418.4,60.5 L418.7,60.5 + L418.7,59.7 L418.9,59.7 L418.9,67.1 L419.1,67.1 L419.1,74.6 L419.3,74.6 L419.3,81.9 L419.5,81.9 + L419.5,89.1 L419.7,89.1 L419.7,96.1 L420.0,96.1 L420.0,103.0 L420.2,103.0 L420.2,109.7 L420.4,109.7 + L420.4,116.3 L420.6,116.3 L420.6,122.8 L420.8,122.8 L420.8,129.1 L421.1,129.1 L421.1,135.3 L421.3,135.3 + L421.3,141.4 L421.5,141.4 L421.5,147.3 L421.7,147.3 L421.7,153.1 L421.9,153.1 L421.9,158.9 L422.1,158.9 + L422.1,164.5 L422.4,164.5 L422.4,169.9 L422.6,169.9 L422.6,175.3 L422.8,175.3 L422.8,180.6 L423.0,180.6 + L423.0,185.7 L423.2,185.7 L423.2,190.8 L423.4,190.8 L423.4,195.7 L423.7,195.7 L423.7,200.6 L423.9,200.6 + L423.9,205.3 L424.1,205.3 L424.1,209.9 L424.3,209.9 L424.3,214.5 L424.5,214.5 L424.5,219.0 L424.7,219.0 + L424.7,223.3 L425.0,223.3 L425.0,227.6 L425.2,227.6 L425.2,231.8 L425.4,231.8 L425.4,235.9 L425.6,235.9 + L425.6,239.9 L425.8,239.9 L425.8,243.9 L426.0,243.9 L426.0,247.7 L426.3,247.7 L426.3,251.5 L426.5,251.5 + L426.5,255.2 L426.7,255.2 L426.7,258.9 L426.9,258.9 L426.9,262.4 L427.1,262.4 L427.1,265.9 L427.3,265.9 + L427.3,269.3 L427.6,269.3 L427.6,272.7 L427.8,272.7 L427.8,275.9 L428.0,275.9 L428.0,279.1 L428.2,279.1 + L428.2,282.3 L428.4,282.3 L428.4,285.4 L428.7,285.4 L428.7,288.4 L428.9,288.4 L428.9,291.3 L429.1,291.3 + L429.1,294.2 L429.3,294.2 L429.3,297.1 L429.5,297.1 L429.5,299.9 L429.7,299.9 L429.7,302.6 L430.0,302.6 + L430.0,305.2 L430.2,305.2 L430.2,307.8 L430.4,307.8 L430.4,310.4 L430.6,310.4 L430.6,312.9 L430.8,312.9 + L430.8,315.4 L431.0,315.4 L431.0,317.8 L431.3,317.8 L431.3,320.1 L431.5,320.1 L431.5,322.4 L431.7,322.4 + L431.7,324.7 L431.9,324.7 L431.9,326.9 L432.1,326.9 L432.1,329.1 L432.3,329.1 L432.3,331.2 L432.6,331.2 + L432.6,333.3 L432.8,333.3 L432.8,335.3 L433.0,335.3 L433.0,337.3 L433.2,337.3 L433.2,339.3 L433.4,339.3 + L433.4,341.2 L433.6,341.2 L433.6,343.1 L433.9,343.1 L433.9,344.9 L434.1,344.9 L434.1,346.7 L434.3,346.7 + L434.3,348.5 L434.5,348.5 L434.5,350.2 L434.7,350.2 L434.7,351.9 L434.9,351.9 L434.9,353.6 L435.2,353.6 + L435.2,355.2 L435.4,355.2 L435.4,356.8 L435.6,356.8 L435.6,358.3 L435.8,358.3 L435.8,359.9 L436.0,359.9 + L436.0,361.4 L436.3,361.4 L436.3,362.8 L436.5,362.8 L436.5,364.3 L436.7,364.3 L436.7,365.7 L436.9,365.7 + L436.9,367.1 L437.1,367.1 L437.1,368.4 L437.3,368.4 L437.3,369.7 L437.6,369.7 L437.6,371.0 L437.8,371.0 + L437.8,372.3 L438.0,372.3 L438.0,373.5 L438.2,373.5 L438.2,374.8 L438.4,374.8 L438.4,376.0 L438.6,376.0 + L438.6,377.1 L438.9,377.1 L438.9,378.3 L439.1,378.3 L439.1,379.4 L439.3,379.4 L439.3,380.5 L439.5,380.5 + L439.5,381.6 L439.7,381.6 L439.7,382.6 L439.9,382.6 L439.9,383.7 L440.2,383.7 L440.2,384.7 L440.4,384.7 + L440.4,385.7 L440.6,385.7 L440.6,386.6 L440.8,386.6 L440.8,387.6 L441.0,387.6 L441.0,388.5 L441.2,388.5 + L441.2,389.4 L441.5,389.4 L441.5,390.3 L441.7,390.3 L441.7,391.2 L441.9,391.2 L441.9,392.1 L442.1,392.1 + L442.1,392.9 L442.3,392.9 L442.3,393.7 L442.5,393.7 L442.5,394.5 L442.8,394.5 L442.8,395.3 L443.0,395.3 + L443.0,396.1 L443.2,396.1 L443.2,396.9 L443.4,396.9 L443.4,397.6 L443.6,397.6 L443.6,398.3 L443.9,398.3 + L443.9,399.0 L444.1,399.0 L444.1,399.7 L444.3,399.7 L444.3,400.4 L444.5,400.4 L444.5,401.1 L444.7,401.1 + L444.7,401.8 L444.9,401.8 L444.9,395.0 L445.2,395.0 L445.2,388.2 L445.4,388.2 L445.4,381.4 L445.6,381.4 + L445.6,374.8 L445.8,374.8 L445.8,368.3 L446.0,368.3 L446.0,362.0 L446.2,362.0 L446.2,355.7 L446.5,355.7 + L446.5,349.6 L446.7,349.6 L446.7,343.6 L446.9,343.6 L446.9,337.6 L447.1,337.6 L447.1,331.8 L447.3,331.8 + L447.3,326.1 L447.5,326.1 L447.5,320.5 L447.8,320.5 L447.8,315.0 L448.0,315.0 L448.0,309.6 L448.2,309.6 + L448.2,304.3 L448.4,304.3 L448.4,299.1 L448.6,299.1 L448.6,294.0 L448.8,294.0 L448.8,289.0 L449.1,289.0 + L449.1,284.1 L449.3,284.1 L449.3,279.2 L449.5,279.2 L449.5,274.5 L449.7,274.5 L449.7,269.8 L449.9,269.8 + L449.9,265.2 L450.1,265.2 L450.1,260.7 L450.4,260.7 L450.4,256.3 L450.6,256.3 L450.6,252.0 L450.8,252.0 + L450.8,247.7 L451.0,247.7 L451.0,243.5 L451.2,243.5 L451.2,239.4 L451.4,239.4 L451.4,235.4 L451.7,235.4 + L451.7,231.4 L451.9,231.4 L451.9,227.5 L452.1,227.5 L452.1,223.7 L452.3,223.7 L452.3,220.0 L452.5,220.0 + L452.5,216.3 L452.8,216.3 L452.8,212.7 L453.0,212.7 L453.0,209.1 L453.2,209.1 L453.2,205.7 L453.4,205.7 + L453.4,202.2 L453.6,202.2 L453.6,198.9 L453.8,198.9 L453.8,195.6 L454.1,195.6 L454.1,192.3 L454.3,192.3 + L454.3,189.2 L454.5,189.2 L454.5,186.0 L454.7,186.0 L454.7,183.0 L454.9,183.0 L454.9,180.0 L455.1,180.0 + L455.1,177.0 L455.4,177.0 L455.4,174.1 L455.6,174.1 L455.6,171.3 L455.8,171.3 L455.8,168.5 L456.0,168.5 + L456.0,165.7 L456.2,165.7 L456.2,163.0 L456.4,163.0 L456.4,160.4 L456.7,160.4 L456.7,157.8 L456.9,157.8 + L456.9,155.2 L457.1,155.2 L457.1,152.7 L457.3,152.7 L457.3,150.2 L457.5,150.2 L457.5,147.8 L457.7,147.8 + L457.7,145.4 L458.0,145.4 L458.0,143.1 L458.2,143.1 L458.2,140.8 L458.4,140.8 L458.4,138.6 L458.6,138.6 + L458.6,136.4 L458.8,136.4 L458.8,134.2 L459.0,134.2 L459.0,132.1 L459.3,132.1 L459.3,130.0 L459.5,130.0 + L459.5,127.9 L459.7,127.9 L459.7,125.9 L459.9,125.9 L459.9,124.0 L460.1,124.0 L460.1,122.0 L460.4,122.0 + L460.4,120.1 L460.6,120.1 L460.6,118.2 L460.8,118.2 L460.8,116.4 L461.0,116.4 L461.0,114.6 L461.2,114.6 + L461.2,112.8 L461.4,112.8 L461.4,111.1 L461.7,111.1 L461.7,109.4 L461.9,109.4 L461.9,107.7 L462.1,107.7 + L462.1,106.0 L462.3,106.0 L462.3,104.4 L462.5,104.4 L462.5,102.8 L462.7,102.8 L462.7,101.3 L463.0,101.3 + L463.0,99.7 L463.2,99.7 L463.2,98.2 L463.4,98.2 L463.4,96.8 L463.6,96.8 L463.6,95.3 L463.8,95.3 + L463.8,93.9 L464.0,93.9 L464.0,92.5 L464.3,92.5 L464.3,91.1 L464.5,91.1 L464.5,89.8 L464.7,89.8 + L464.7,88.5 L464.9,88.5 L464.9,87.2 L465.1,87.2 L465.1,85.9 L465.3,85.9 L465.3,84.6 L465.6,84.6 + L465.6,83.4 L465.8,83.4 L465.8,82.2 L466.0,82.2 L466.0,81.0 L466.2,81.0 L466.2,79.8 L466.4,79.8 + L466.4,78.7 L466.6,78.7 L466.6,77.6 L466.9,77.6 L466.9,76.5 L467.1,76.5 L467.1,75.4 L467.3,75.4 + L467.3,74.3 L467.5,74.3 L467.5,73.3 L467.7,73.3 L467.7,72.3 L468.0,72.3 L468.0,71.3 L468.2,71.3 + L468.2,70.3 L468.4,70.3 L468.4,69.3 L468.6,69.3 L468.6,68.3 L468.8,68.3 L468.8,67.4 L469.0,67.4 + L469.0,66.5 L469.3,66.5 L469.3,65.6 L469.5,65.6 L469.5,64.7 L469.7,64.7 L469.7,63.8 L469.9,63.8 + L469.9,63.0 L470.1,63.0 L470.1,62.1 L470.3,62.1 L470.3,61.3 L470.6,61.3 L470.6,60.5 L470.8,60.5 + L470.8,59.7 L471.0,59.7 L471.0,67.1 L471.2,67.1 L471.2,74.6 L471.4,74.6 L471.4,81.9 L471.6,81.9 + L471.6,89.0 L471.9,89.0 L471.9,96.1 L472.1,96.1 L472.1,102.9 L472.3,102.9 L472.3,109.7 L472.5,109.7 + L472.5,116.3 L472.7,116.3 L472.7,122.7 L472.9,122.7 L472.9,129.1 L473.2,129.1 L473.2,135.3 L473.4,135.3 + L473.4,141.3 L473.6,141.3 L473.6,147.3 L473.8,147.3 L473.8,153.1 L474.0,153.1 L474.0,158.8 L474.2,158.8 + L474.2,164.4 L474.5,164.4 L474.5,169.9 L474.7,169.9 L474.7,175.3 L474.9,175.3 L474.9,180.5 L475.1,180.5 + L475.1,185.7 L475.3,185.7 L475.3,190.7 L475.6,190.7 L475.6,195.7 L475.8,195.7 L475.8,200.5 L476.0,200.5 + L476.0,205.3 L476.2,205.3 L476.2,209.9 L476.4,209.9 L476.4,214.5 L476.6,214.5 L476.6,218.9 L476.9,218.9 + L476.9,223.3 L477.1,223.3 L477.1,227.6 L477.3,227.6 L477.3,231.8 L477.5,231.8 L477.5,235.9 L477.7,235.9 + L477.7,239.9 L477.9,239.9 L477.9,243.9 L478.2,243.9 L478.2,247.7 L478.4,247.7 L478.4,251.5 L478.6,251.5 + L478.6,255.2 L478.8,255.2 L478.8,258.9 L479.0,258.9 L479.0,262.4 L479.2,262.4 L479.2,265.9 L479.5,265.9 + L479.5,269.3 L479.7,269.3 L479.7,272.7 L479.9,272.7 L479.9,275.9 L480.1,275.9 L480.1,279.1 L480.3,279.1 + L480.3,282.3 L480.5,282.3 L480.5,285.4 L480.8,285.4 L480.8,288.4 L481.0,288.4 L481.0,291.3 L481.2,291.3 + L481.2,294.2 L481.4,294.2 L481.4,297.1 L481.6,297.1 L481.6,299.8 L481.8,299.8 L481.8,302.6 L482.1,302.6 + L482.1,305.2 L482.3,305.2 L482.3,307.8 L482.5,307.8 L482.5,310.4 L482.7,310.4 L482.7,312.9 L482.9,312.9 + L482.9,315.4 L483.1,315.4 L483.1,317.8 L483.4,317.8 L483.4,320.1 L483.6,320.1 L483.6,322.4 L483.8,322.4 + L483.8,324.7 L484.0,324.7 L484.0,326.9 L484.2,326.9 L484.2,329.1 L484.5,329.1 L484.5,331.2 L484.7,331.2 + L484.7,333.3 L484.9,333.3 L484.9,335.3 L485.1,335.3 L485.1,337.3 L485.3,337.3 L485.3,339.3 L485.5,339.3 + L485.5,341.2 L485.8,341.2 L485.8,343.1 L486.0,343.1 L486.0,344.9 L486.2,344.9 L486.2,346.7 L486.4,346.7 + L486.4,348.5 L486.6,348.5 L486.6,350.2 L486.8,350.2 L486.8,351.9 L487.1,351.9 L487.1,353.6 L487.3,353.6 + L487.3,355.2 L487.5,355.2 L487.5,356.8 L487.7,356.8 L487.7,358.3 L487.9,358.3 L487.9,359.9 L488.1,359.9 + L488.1,361.4 L488.4,361.4 L488.4,362.8 L488.6,362.8 L488.6,364.3 L488.8,364.3 L488.8,365.7 L489.0,365.7 + L489.0,367.1 L489.2,367.1 L489.2,368.4 L489.4,368.4 L489.4,369.7 L489.7,369.7 L489.7,371.0 L489.9,371.0 + L489.9,372.3 L490.1,372.3 L490.1,373.5 L490.3,373.5 L490.3,374.8 L490.5,374.8 L490.5,376.0 L490.7,376.0 + L490.7,377.1 L491.0,377.1 L491.0,378.3 L491.2,378.3 L491.2,379.4 L491.4,379.4 L491.4,380.5 L491.6,380.5 + L491.6,381.6 L491.8,381.6 L491.8,382.6 L492.1,382.6 L492.1,383.7 L492.3,383.7 L492.3,384.7 L492.5,384.7 + L492.5,385.7 L492.7,385.7 L492.7,386.6 L492.9,386.6 L492.9,387.6 L493.1,387.6 L493.1,388.5 L493.4,388.5 + L493.4,389.4 L493.6,389.4 L493.6,390.3 L493.8,390.3 L493.8,391.2 L494.0,391.2 L494.0,392.1 L494.2,392.1 + L494.2,392.9 L494.4,392.9 L494.4,393.7 L494.7,393.7 L494.7,394.5 L494.9,394.5 L494.9,395.3 L495.1,395.3 + L495.1,396.1 L495.3,396.1 L495.3,396.9 L495.5,396.9 L495.5,397.6 L495.7,397.6 L495.7,398.3 L496.0,398.3 + L496.0,399.0 L496.2,399.0 L496.2,399.7 L496.4,399.7 L496.4,400.4 L496.6,400.4 L496.6,401.1 L496.8,401.1 + L496.8,401.8 L497.0,401.8 L497.0,395.0 L497.3,395.0 L497.3,388.2 L497.5,388.2 L497.5,381.5 L497.7,381.5 + L497.7,374.9 L497.9,374.9 L497.9,368.4 L498.1,368.4 L498.1,362.0 L498.3,362.0 L498.3,355.8 L498.6,355.8 + L498.6,349.6 L498.8,349.6 L498.8,343.6 L499.0,343.6 L499.0,337.7 L499.2,337.7 L499.2,331.9 L499.4,331.9 + L499.4,326.2 L499.7,326.2 L499.7,320.6 L499.9,320.6 L499.9,315.1 L500.1,315.1 L500.1,309.7 L500.3,309.7 + L500.3,304.3 L500.5,304.3 L500.5,299.1 L500.7,299.1 L500.7,294.0 L501.0,294.0 L501.0,289.0 L501.2,289.0 + L501.2,284.1 L501.4,284.1 L501.4,279.2 L501.6,279.2 L501.6,274.5 L501.8,274.5 L501.8,269.8 L502.0,269.8 + L502.0,265.2 L502.3,265.2 L502.3,260.7 L502.5,260.7 L502.5,256.3 L502.7,256.3 L502.7,252.0 L502.9,252.0 + L502.9,247.7 L503.1,247.7 L503.1,243.5 L503.3,243.5 L503.3,239.4 L503.6,239.4 L503.6,235.4 L503.8,235.4 + L503.8,231.4 L504.0,231.4 L504.0,227.6 L504.2,227.6 L504.2,223.7 L504.4,223.7 L504.4,220.0 L504.6,220.0 + L504.6,216.3 L504.9,216.3 L504.9,212.7 L505.1,212.7 L505.1,209.1 L505.3,209.1 L505.3,205.7 L505.5,205.7 + L505.5,202.2 L505.7,202.2 L505.7,198.9 L505.9,198.9 L505.9,195.6 L506.2,195.6 L506.2,192.3 L506.4,192.3 + L506.4,189.2 L506.6,189.2 L506.6,186.0 L506.8,186.0 L506.8,183.0 L507.0,183.0 L507.0,180.0 L507.2,180.0 + L507.2,177.0 L507.5,177.0 L507.5,174.1 L507.7,174.1 L507.7,171.3 L507.9,171.3 L507.9,168.5 L508.1,168.5 + L508.1,165.7 L508.3,165.7 L508.3,163.0 L508.6,163.0 L508.6,160.4 L508.8,160.4 L508.8,157.8 L509.0,157.8 + L509.0,155.2 L509.2,155.2 L509.2,152.7 L509.4,152.7 L509.4,150.2 L509.6,150.2 L509.6,147.8 L509.9,147.8 + L509.9,145.5 L510.1,145.5 L510.1,143.1 L510.3,143.1 L510.3,140.8 L510.5,140.8 L510.5,138.6 L510.7,138.6 + L510.7,136.4 L510.9,136.4 L510.9,134.2 L511.2,134.2 L511.2,132.1 L511.4,132.1 L511.4,130.0 L511.6,130.0 + L511.6,127.9 L511.8,127.9 L511.8,125.9 L512.0,125.9 L512.0,124.0 L512.2,124.0 L512.2,122.0 L512.5,122.0 + L512.5,120.1 L512.7,120.1 L512.7,118.2 L512.9,118.2 L512.9,116.4 L513.1,116.4 L513.1,114.6 L513.3,114.6 + L513.3,112.8 L513.5,112.8 L513.5,111.1 L513.8,111.1 L513.8,109.4 L514.0,109.4 L514.0,107.7 L514.2,107.7 + L514.2,106.0 L514.4,106.0 L514.4,104.4 L514.6,104.4 L514.6,102.8 L514.8,102.8 L514.8,101.3 L515.1,101.3 + L515.1,99.8 L515.3,99.8 L515.3,98.2 L515.5,98.2 L515.5,96.8 L515.7,96.8 L515.7,95.3 L515.9,95.3 + L515.9,93.9 L516.2,93.9 L516.2,92.5 L516.4,92.5 L516.4,91.1 L516.6,91.1 L516.6,89.8 L516.8,89.8 + L516.8,88.5 L517.0,88.5 L517.0,87.2 L517.2,87.2 L517.2,85.9 L517.5,85.9 L517.5,84.6 L517.7,84.6 + L517.7,83.4 L517.9,83.4 L517.9,82.2 L518.1,82.2 L518.1,81.0 L518.3,81.0 L518.3,79.8 L518.5,79.8 + L518.5,78.7 L518.8,78.7 L518.8,77.6 L519.0,77.6 L519.0,76.5 L519.2,76.5 L519.2,75.4 L519.4,75.4 + L519.4,74.3 L519.6,74.3 L519.6,73.3 L519.8,73.3 L519.8,72.3 L520.1,72.3 L520.1,71.3 L520.3,71.3 + L520.3,70.3 L520.5,70.3 L520.5,69.3 L520.7,69.3 L520.7,68.4 L520.9,68.4 L520.9,67.4 L521.1,67.4 + L521.1,66.5 L521.4,66.5 L521.4,65.6 L521.6,65.6 L521.6,64.7 L521.8,64.7 L521.8,63.8 L522.0,63.8 + L522.0,63.0 L522.2,63.0 L522.2,62.2 L522.4,62.2 L522.4,61.3 L522.7,61.3 L522.7,60.5 L522.9,60.5 + L522.9,59.7 L523.1,59.7 L523.1,67.1 L523.3,67.1 L523.3,74.5 L523.5,74.5 L523.5,81.8 L523.8,81.8 + L523.8,89.0 L524.0,89.0 L524.0,96.0 L524.2,96.0 L524.2,102.9 L524.4,102.9 L524.4,109.6 L524.6,109.6 + L524.6,116.2 L524.8,116.2 L524.8,122.7 L525.1,122.7 L525.1,129.0 L525.3,129.0 L525.3,135.2 L525.5,135.2 + L525.5,141.3 L525.7,141.3 L525.7,147.3 L525.9,147.3 L525.9,153.1 L526.1,153.1 L526.1,158.8 L526.4,158.8 + L526.4,164.4 L526.6,164.4 L526.6,169.9 L526.8,169.9 L526.8,175.3 L527.0,175.3 L527.0,180.5 L527.2,180.5 + L527.2,185.7 L527.4,185.7 L527.4,190.7 L527.7,190.7 L527.7,195.7 L527.9,195.7 L527.9,200.5 L528.1,200.5 + L528.1,205.3 L528.3,205.3 L528.3,209.9 L528.5,209.9 L528.5,214.5 L528.7,214.5 L528.7,218.9 L529.0,218.9 + L529.0,223.3 L529.2,223.3 L529.2,227.6 L529.4,227.6 L529.4,231.8 L529.6,231.8 L529.6,235.9 L529.8,235.9 + L529.8,239.9 L530.0,239.9 L530.0,243.9 L530.3,243.9 L530.3,247.7 L530.5,247.7 L530.5,251.5 L530.7,251.5 + L530.7,255.2 L530.9,255.2 L530.9,258.8 L531.1,258.8 L531.1,262.4 L531.4,262.4 L531.4,265.9 L531.6,265.9 + L531.6,269.3 L531.8,269.3 L531.8,272.6 L532.0,272.6 L532.0,275.9 L532.2,275.9 L532.2,279.1 L532.4,279.1 + L532.4,282.3 L532.7,282.3 L532.7,285.3 L532.9,285.3 L532.9,288.4 L533.1,288.4 L533.1,291.3 L533.3,291.3 + L533.3,294.2 L533.5,294.2 L533.5,297.1 L533.7,297.1 L533.7,299.8 L534.0,299.8 L534.0,302.6 L534.2,302.6 + L534.2,305.2 L534.4,305.2 L534.4,307.8 L534.6,307.8 L534.6,310.4 L534.8,310.4 L534.8,312.9 L535.0,312.9 + L535.0,315.3 L535.3,315.3 L535.3,317.8 L535.5,317.8 L535.5,320.1 L535.7,320.1 L535.7,322.4 L535.9,322.4 + L535.9,324.7 L536.1,324.7 L536.1,326.9 L536.3,326.9 L536.3,329.1 L536.6,329.1 L536.6,331.2 L536.8,331.2 + L536.8,333.3 L537.0,333.3 L537.0,335.3 L537.2,335.3 L537.2,337.3 L537.4,337.3 L537.4,339.3 L537.6,339.3 + L537.6,341.2 L537.9,341.2 L537.9,343.1 L538.1,343.1 L538.1,344.9 L538.3,344.9 L538.3,346.7 L538.5,346.7 + L538.5,348.5 L538.7,348.5 L538.7,350.2 L538.9,350.2 L538.9,351.9 L539.2,351.9 L539.2,353.6 L539.4,353.6 + L539.4,355.2 L539.6,355.2 L539.6,356.8 L539.8,356.8 L539.8,358.3 L540.0,358.3 L540.0,359.9 L540.3,359.9 + L540.3,361.4 L540.5,361.4 L540.5,362.8 L540.7,362.8 L540.7,364.3 L540.9,364.3 L540.9,365.7 L541.1,365.7 + L541.1,367.1 L541.3,367.1 L541.3,368.4 L541.6,368.4 L541.6,369.7 L541.8,369.7 L541.8,371.0 L542.0,371.0 + L542.0,372.3 L542.2,372.3 L542.2,373.5 L542.4,373.5 L542.4,374.8 L542.6,374.8 L542.6,376.0 L542.9,376.0 + L542.9,377.1 L543.1,377.1 L543.1,378.3 L543.3,378.3 L543.3,379.4 L543.5,379.4 L543.5,380.5 L543.7,380.5 + L543.7,381.6 L543.9,381.6 L543.9,382.6 L544.2,382.6 L544.2,383.7 L544.4,383.7 L544.4,384.7 L544.6,384.7 + L544.6,385.7 L544.8,385.7 L544.8,386.6 L545.0,386.6 L545.0,387.6 L545.2,387.6 L545.2,388.5 L545.5,388.5 + L545.5,389.4 L545.7,389.4 L545.7,390.3 L545.9,390.3 L545.9,391.2 L546.1,391.2 L546.1,392.1 L546.3,392.1 + L546.3,392.9 L546.5,392.9 L546.5,393.7 L546.8,393.7 L546.8,394.5 L547.0,394.5 L547.0,395.3 L547.2,395.3 + L547.2,396.1 L547.4,396.1 L547.4,396.9 L547.6,396.9 L547.6,397.6 L547.9,397.6 L547.9,398.3 L548.1,398.3 + L548.1,399.0 L548.3,399.0 L548.3,399.7 L548.5,399.7 L548.5,400.4 L548.7,400.4 L548.7,401.1 L548.9,401.1 + L548.9,401.8 L549.2,401.8 L549.2,395.1 L549.4,395.1 L549.4,388.2 L549.6,388.2 L549.6,381.5 L549.8,381.5 + L549.8,374.9 L550.0,374.9 L550.0,368.4 L550.2,368.4 L550.2,362.0 L550.5,362.0 L550.5,355.8 L550.7,355.8 + L550.7,349.6 L550.9,349.6 L550.9,343.6 L551.1,343.6 L551.1,337.7 L551.3,337.7 L551.3,331.9 L551.5,331.9 + L551.5,326.2 L551.8,326.2 L551.8,320.6 L552.0,320.6 L552.0,315.1 L552.2,315.1 L552.2,309.7 L552.4,309.7 + L552.4,304.4 L552.6,304.4 L552.6,299.2 L552.8,299.2 L552.8,294.0 L553.1,294.0 L553.1,289.0 L553.3,289.0 + L553.3,284.1 L553.5,284.1 L553.5,279.3 L553.7,279.3 L553.7,274.5 L553.9,274.5 L553.9,269.8 L554.1,269.8 + L554.1,265.3 L554.4,265.3 L554.4,260.8 L554.6,260.8 L554.6,256.3 L554.8,256.3 L554.8,252.0 L555.0,252.0 + L555.0,247.7 L555.2,247.7 L555.2,243.6 L555.5,243.6 L555.5,239.4 L555.7,239.4 L555.7,235.4 L555.9,235.4 + L555.9,231.5 L556.1,231.5 L556.1,227.6 L556.3,227.6 L556.3,223.8 L556.5,223.8 L556.5,220.0 L556.8,220.0 + L556.8,216.3 L557.0,216.3 L557.0,212.7 L557.2,212.7 L557.2,209.2 L557.4,209.2 L557.4,205.7 L557.6,205.7 + L557.6,202.3 L557.8,202.3 L557.8,198.9 L558.1,198.9 L558.1,195.6 L558.3,195.6 L558.3,192.4 L558.5,192.4 + L558.5,189.2 L558.7,189.2 L558.7,186.1 L558.9,186.1 L558.9,183.0 L559.1,183.0 L559.1,180.0 L559.4,180.0 + L559.4,177.0 L559.6,177.0 L559.6,174.1 L559.8,174.1 L559.8,171.3 L560.0,171.3 L560.0,168.5 L560.2,168.5 + L560.2,165.7 L560.4,165.7 L560.4,163.0 L560.7,163.0 L560.7,160.4 L560.9,160.4 L560.9,157.8 L561.1,157.8 + L561.1,155.2 L561.3,155.2 L561.3,152.7 L561.5,152.7 L561.5,150.3 L561.7,150.3 L561.7,147.8 L562.0,147.8 + L562.0,145.5 L562.2,145.5 L562.2,143.1 L562.4,143.1 L562.4,140.8 L562.6,140.8 L562.6,138.6 L562.8,138.6 + L562.8,136.4 L563.1,136.4 L563.1,134.2 L563.3,134.2 L563.3,132.1 L563.5,132.1 L563.5,130.0 L563.7,130.0 + L563.7,128.0 L563.9,128.0 L563.9,125.9 L564.1,125.9 L564.1,124.0 L564.4,124.0 L564.4,122.0 L564.6,122.0 + L564.6,120.1 L564.8,120.1 L564.8,118.2 L565.0,118.2 L565.0,116.4 L565.2,116.4 L565.2,114.6 L565.4,114.6 + L565.4,112.8 L565.7,112.8 L565.7,111.1 L565.9,111.1 L565.9,109.4 L566.1,109.4 L566.1,107.7 L566.3,107.7 + L566.3,106.1 L566.5,106.1 L566.5,104.4 L566.7,104.4 L566.7,102.9 L567.0,102.9 L567.0,101.3 L567.2,101.3 + L567.2,99.8 L567.4,99.8 L567.4,98.3 L567.6,98.3 L567.6,96.8 L567.8,96.8 L567.8,95.3 L568.0,95.3 + L568.0,93.9 L568.3,93.9 L568.3,92.5 L568.5,92.5 L568.5,91.1 L568.7,91.1 L568.7,89.8 L568.9,89.8 + L568.9,88.5 L569.1,88.5 L569.1,87.2 L569.3,87.2 L569.3,85.9 L569.6,85.9 L569.6,84.6 L569.8,84.6 + L569.8,83.4 L570.0,83.4 L570.0,82.2 L570.2,82.2 L570.2,81.0 L570.4,81.0 L570.4,79.9 L570.6,79.9 + L570.6,78.7 L570.9,78.7 L570.9,77.6 L571.1,77.6 L571.1,76.5 L571.3,76.5 L571.3,75.4 L571.5,75.4 + L571.5,74.3 L571.7,74.3 L571.7,73.3 L572.0,73.3 L572.0,72.3 L572.2,72.3 L572.2,71.3 L572.4,71.3 + L572.4,70.3 L572.6,70.3 L572.6,69.3 L572.8,69.3 L572.8,68.4 L573.0,68.4 L573.0,67.4 L573.3,67.4 + L573.3,66.5 L573.5,66.5 L573.5,65.6 L573.7,65.6 L573.7,64.7 L573.9,64.7 L573.9,63.8 L574.1,63.8 + L574.1,63.0 L574.3,63.0 L574.3,62.2 L574.6,62.2 L574.6,61.3 L574.8,61.3 L574.8,60.5 L575.0,60.5 + L575.0,59.7 '/></g> + </g> + <g id="gnuplot_plot_2" ><title>gnuplot_plot_2</title> +<g style="fill:none; color:green; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter"> + <g transform="translate(507.9,57.2)" style="stroke:none; fill:black; font-family:Arial; font-size:12.00pt; text-anchor:end"> + <text>I</text> + </g> + <path d='M516.2,52.7 L558.4,52.7 M53.9,444.0 L53.9,433.3 L80.0,433.3 L80.0,16.7 L106.0,16.7 L106.0,433.3 + L132.1,433.3 L132.1,16.7 L158.1,16.7 L158.1,433.3 L184.2,433.3 L184.2,16.7 L210.2,16.7 L210.2,433.3 + L236.3,433.3 L236.3,16.7 L262.3,16.7 L262.3,433.3 L288.4,433.3 L288.4,16.7 L314.5,16.7 L314.5,433.3 + L340.5,433.3 L340.5,16.7 L366.6,16.7 L366.6,433.3 L392.6,433.3 L392.6,16.7 L418.7,16.7 L418.7,433.3 + L444.7,433.3 L444.7,16.7 L470.8,16.7 L470.8,433.3 L496.8,433.3 L496.8,16.7 L522.9,16.7 L522.9,433.3 + L548.9,433.3 L548.9,16.7 '/></g> + </g> +<g style="fill:none; color:black; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter"> + <path stroke='black' d='M53.9,16.7 L53.9,444.0 L575.0,444.0 L575.0,16.7 L53.9,16.7 Z '/></g> +</g> +</svg> + diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 7b171e851ed..c4d402ff3ee 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -18,18 +18,20 @@ namespace netlist { -#if (NL_USE_MEMPOOL) -static plib::mempool p(65536, 8); +namespace detail +{ +#if (USE_MEMPOOL) +static plib::mempool pool(65536, 8); void * object_t::operator new (size_t size) { - return p.alloc(size); + return pool.alloc(size); } void object_t::operator delete (void * mem) { if (mem) - p.free(mem); + pool.free(mem); } #else void * object_t::operator new (size_t size) @@ -44,6 +46,8 @@ void object_t::operator delete (void * mem) } #endif +} + // ---------------------------------------------------------------------------------------- // logic_family_ttl_t // ---------------------------------------------------------------------------------------- @@ -101,7 +105,7 @@ const logic_family_desc_t *family_CD4XXX() // queue_t // ---------------------------------------------------------------------------------------- -queue_t::queue_t(netlist_t &nl) +detail::queue_t::queue_t(netlist_t &nl) : timed_queue<net_t *, netlist_time>(512) , object_t("QUEUE") , netlist_ref(nl) @@ -112,7 +116,7 @@ queue_t::queue_t(netlist_t &nl) { } -void queue_t::register_state(plib::state_manager_t &manager, const pstring &module) +void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module) { netlist().log().debug("register_state\n"); manager.save_item(this, m_qsize, module + "." + "qsize"); @@ -120,30 +124,30 @@ void queue_t::register_state(plib::state_manager_t &manager, const pstring &modu manager.save_item(this, &(m_names[0].m_buf[0]), module + "." + "names", m_names.size() * sizeof(names_t)); } -void queue_t::on_pre_save() +void detail::queue_t::on_pre_save() { netlist().log().debug("on_pre_save\n"); m_qsize = this->size(); netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize); - for (int i = 0; i < m_qsize; i++ ) + for (std::size_t i = 0; i < m_qsize; i++ ) { m_times[i] = this->listptr()[i].m_exec_time.as_raw(); pstring p = this->listptr()[i].m_object->name(); - int n = p.len(); - n = std::min(63, n); + std::size_t n = p.len(); + if (n > 63) n = 63; std::strncpy(m_names[i].m_buf, p.cstr(), n); m_names[i].m_buf[n] = 0; } } -void queue_t::on_post_load() +void detail::queue_t::on_post_load() { this->clear(); netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize); - for (int i = 0; i < m_qsize; i++ ) + for (std::size_t i = 0; i < m_qsize; i++ ) { - net_t *n = netlist().find_net(m_names[i].m_buf); + detail::net_t *n = netlist().find_net(m_names[i].m_buf); //log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n)); //log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double())); this->push(netlist_time::from_raw(m_times[i]), n); @@ -154,16 +158,16 @@ void queue_t::on_post_load() // object_t // ---------------------------------------------------------------------------------------- -object_t::object_t(const pstring &aname) +detail::object_t::object_t(const pstring &aname) : m_name(aname) { } -object_t::~object_t() +detail::object_t::~object_t() { } -const pstring &object_t::name() const +const pstring &detail::object_t::name() const { return m_name; } @@ -172,7 +176,7 @@ const pstring &object_t::name() const // device_object_t // ---------------------------------------------------------------------------------------- -device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const type_t atype) +detail::device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const type_t atype) : object_t(aname) , m_device(dev) , m_type(atype) @@ -227,6 +231,60 @@ void netlist_t::start() { /* load the library ... */ + /* make sure the solver and parameters are started first! */ + + for (auto & e : setup().m_device_factory) + { + if ( setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second) + || setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second) + || setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second) + || setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) + { + auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first)); + register_dev(std::move(dev)); + } + } + + log().debug("Searching for mainclock and solver ...\n"); + + m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock"); + m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver"); + m_gnd = get_single_device<devices::NETLIB_NAME(gnd)>("gnd"); + m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); + + /* create devices */ + + for (auto & e : setup().m_device_factory) + { + if ( !setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second) + && !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second) + && !setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second) + && !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) + { + auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first)); + register_dev(std::move(dev)); + } + } + + bool use_deactivate = (m_params->m_use_deactivate() ? true : false); + + for (auto &d : m_devices) + { + if (use_deactivate) + { + auto p = setup().m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE"); + if (p != setup().m_param_values.end()) + { + //FIXME: Error checking + auto v = p->second.as_long(); + d->set_hint_deactivate(!v); + } + } + else + d->set_hint_deactivate(false); + } + + pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); m_lib = plib::palloc<plib::dynlib>(libpath); @@ -243,7 +301,7 @@ void netlist_t::stop() dev->stop_dev(); } -net_t *netlist_t::find_net(const pstring &name) +detail::net_t *netlist_t::find_net(const pstring &name) { for (auto & net : m_nets) if (net->name() == name) @@ -291,8 +349,9 @@ void netlist_t::reset() * It is however not acceptable that this depends on the startup order. * Best would be, if reset would call update_dev for devices which need it. */ - for (int i = m_devices.size() - 1; i >= 0; i--) - m_devices[i]->update_dev(); + std::size_t i = m_devices.size(); + while (i>0) + m_devices[--i]->update_dev(); #endif } @@ -307,7 +366,7 @@ void netlist_t::process_queue(const netlist_time &delta) if (m_mainclock == nullptr) { - queue_t::entry_t e(m_queue.pop()); + detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; while (e.m_object != nullptr) { @@ -333,7 +392,7 @@ void netlist_t::process_queue(const netlist_time &delta) mc_net.update_devs(); } - const queue_t::entry_t e(m_queue.pop()); + const detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; if (e.m_object == nullptr) break; @@ -379,7 +438,9 @@ void netlist_t::print_stats() const } overhead.stop(); - uint_least64_t total_overhead = (uint_least64_t) overhead()*(uint_least64_t)total_count/(uint_least64_t)200000; + nperftime_t::type total_overhead = overhead() + * static_cast<nperftime_t::type>(total_count) + / static_cast<nperftime_t::type>(200000); log().verbose("Queue Pushes {1:15}", queue().m_prof_call()); log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove()); @@ -391,7 +452,9 @@ void netlist_t::print_stats() const log().verbose(""); 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); - log().verbose("Overhead per pop {1:11}", (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead ))/queue().m_prof_call()); + nperftime_t::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) + / static_cast<nperftime_t::type>(queue().m_prof_call()); + log().verbose("Overhead per pop {1:11}", overhead_per_pop ); log().verbose(""); for (auto &entry : m_devices) { @@ -478,20 +541,6 @@ void core_device_t::stop_dev() //stop(); } -netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp) -{ - if (inp.state() != logic_t::STATE_INP_PASSIVE) - return inp.Q(); - else - { - inp.activate(); - const netlist_sig_t ret = inp.Q(); - inp.inactivate(); - return ret; - } -} - - // ---------------------------------------------------------------------------------------- // device_t // ---------------------------------------------------------------------------------------- @@ -506,7 +555,7 @@ setup_t &device_t::setup() return netlist().setup(); } -void device_t::register_subalias(const pstring &name, core_terminal_t &term) +void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term) { pstring alias = this->name() + "." + name; @@ -523,7 +572,7 @@ void device_t::register_subalias(const pstring &name, const pstring &aliased) setup().register_alias_nofqn(alias, aliased_fqn); } -void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2) +void device_t::connect_late(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { setup().register_link_fqn(t1.name(), t2.name()); } @@ -536,7 +585,7 @@ void device_t::connect_late(const pstring &t1, const pstring &t2) /* FIXME: this is only used by solver code since matrix solvers are started in * post_start. */ -void device_t::connect_post_start(core_terminal_t &t1, core_terminal_t &t2) +void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { if (!setup().connect(t1, t2)) netlist().log().fatal("Error connecting {1} to {2}\n", t1.name(), t2.name()); @@ -547,12 +596,12 @@ void device_t::connect_post_start(core_terminal_t &t1, core_terminal_t &t2) // family_setter_t // ----------------------------------------------------------------------------- -family_setter_t::family_setter_t(core_device_t &dev, const char *desc) +detail::family_setter_t::family_setter_t(core_device_t &dev, const char *desc) { dev.set_logic_family(dev.netlist().setup().family_from_model(desc)); } -family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc) +detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc) { dev.set_logic_family(desc); } @@ -568,7 +617,7 @@ struct do_nothing_deleter{ }; -net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : object_t(aname) , netlist_ref(nl) , m_new_Q(*this, "m_new_Q", 0) @@ -586,16 +635,16 @@ net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) nl.m_nets.push_back(plib::owned_ptr<net_t>(this, true)); } -net_t::~net_t() +detail::net_t::~net_t() { netlist().state().remove_save_items(this); } -void net_t::inc_active(core_terminal_t &term) +void detail::net_t::inc_active(core_terminal_t &term) { m_active++; m_list_active.push_front(&term); - nl_assert(m_active <= (int) num_cons()); + nl_assert(m_active <= static_cast<int>(num_cons())); if (m_active == 1) { railterminal().device().do_inc_active(); @@ -615,7 +664,7 @@ void net_t::inc_active(core_terminal_t &term) } } -void net_t::dec_active(core_terminal_t &term) +void detail::net_t::dec_active(core_terminal_t &term) { --m_active; nl_assert(m_active >= 0); @@ -624,7 +673,7 @@ void net_t::dec_active(core_terminal_t &term) railterminal().device().do_dec_active(); } -void net_t::rebuild_list() +void detail::net_t::rebuild_list() { /* rebuild m_list */ @@ -639,7 +688,7 @@ void net_t::rebuild_list() m_active = cnt; } -void net_t::update_devs() +void detail::net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); @@ -665,7 +714,7 @@ void net_t::update_devs() } } -void net_t::reset() +void detail::net_t::reset() { m_time = netlist_time::zero(); m_active = 0; @@ -689,7 +738,7 @@ void net_t::reset() m_active++; } -void net_t::register_con(core_terminal_t &terminal) +void detail::net_t::register_con(detail::core_terminal_t &terminal) { terminal.set_net(this); @@ -699,15 +748,15 @@ void net_t::register_con(core_terminal_t &terminal) m_active++; } -void net_t::move_connections(net_t *dest_net) +void detail::net_t::move_connections(detail::net_t *dest_net) { - for (core_terminal_t *ct : m_core_terms) + for (auto &ct : m_core_terms) dest_net->register_con(*ct); m_core_terms.clear(); m_active = 0; } -void net_t::merge_net(net_t *othernet) +void detail::net_t::merge_net(detail::net_t *othernet) { netlist().log().debug("merging nets ...\n"); if (othernet == nullptr) @@ -738,7 +787,7 @@ void net_t::merge_net(net_t *othernet) // logic_net_t // ---------------------------------------------------------------------------------------- -logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr) : net_t(nl, aname, mr) { } @@ -748,7 +797,7 @@ logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *m // analog_net_t // ---------------------------------------------------------------------------------------- -analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr) : net_t(nl, aname, mr) , m_solver(nullptr) { @@ -772,7 +821,7 @@ void analog_net_t::process_net(std::vector<list_t> &groups) return; /* add the net */ groups.back().push_back(this); - for (core_terminal_t *p : m_core_terms) + for (auto &p : m_core_terms) { if (p->is_type(terminal_t::TERMINAL)) { @@ -789,7 +838,7 @@ void analog_net_t::process_net(std::vector<list_t> &groups) // core_terminal_t // ---------------------------------------------------------------------------------------- -core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype) +detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype) : device_object_t(dev, dev.name() + "." + aname, atype) , plib::linkedlist_t<core_terminal_t>::element_t() , m_net(nullptr) @@ -797,7 +846,7 @@ core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const { } -void core_terminal_t::reset() +void detail::core_terminal_t::reset() { if (is_type(OUTPUT)) set_state(STATE_OUT); @@ -805,12 +854,12 @@ void core_terminal_t::reset() set_state(STATE_INP_ACTIVE); } -void core_terminal_t::set_net(net_t *anet) +void detail::core_terminal_t::set_net(net_t *anet) { m_net = anet; } - void core_terminal_t::clear_net() + void detail::core_terminal_t::clear_net() { m_net = nullptr; } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 9a0c9b824bf..fbd67862dd7 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1,154 +1,8 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/* - * nlbase.h +/*! * - * A mixed signal circuit simulation - * - * D: Device - * O: Rail output (output) - * I: Infinite impedance input (input) - * T: Terminal (finite impedance) - * - * +---+ +---+ +---+ +---+ +---+ - * | | | | | | | | | | - * | D | | D | | D | | D | | D | - * | | | | | | | | | | - * +-O-+ +-I-+ +-I-+ +-T-+ +-T-+ - * | | | | | - * +-+---------+---------+---------+---------+-+ - * | rail net | - * +-------------------------------------------+ - * - * A rail net is a net which is driven by exactly one output with an - * (idealized) internal resistance of zero. - * Ideally, it can deliver infinite current. - * - * A infinite resistance input does not source or sink current. - * - * Terminals source or sink finite (but never zero) current. - * - * The system differentiates between analog and logic input and outputs and - * analog terminals. Analog and logic devices can not be connected to the - * same net. Instead, proxy devices are inserted automatically: - * - * +---+ +---+ - * | | | | - * | D1| | D2| - * | A | | L | - * +-O-+ +-I-+ - * | | - * +-+---------+---+ - * | rail net | - * +---------------+ - * - * is converted into - * +----------+ - * | | - * +---+ +-+-+ | +---+ - * | | | L | A-L | | | - * | D1| | D | Proxy | | D2| - * | A | | A | | | | - * +-O-+ +-I-+ | +-I-+ - * | | | | - * +-+---------+--+ +-+-----+-------+ - * | rail net (A) | | rail net (L) | - * +--------------| +---------------+ - * - * This works both analog to logic as well as logic to analog. - * - * The above is an advanced implementation of the existing discrete - * subsystem in MAME. Instead of relying on a fixed time-step, analog devices - * could either connect to fixed time-step clock or use an internal clock - * to update them. This would however introduce macro devices for RC, diodes - * and transistors again. - * - * ============================================================================ - * - * Instead, the following approach in case of a pure terminal/input network - * is taken: - * - * +---+ +---+ +---+ +---+ +---+ - * | | | | | | | | | | - * | D | | D | | D | | D | | D | - * | | | | | | | | | | - * +-T-+ +-I-+ +-I-+ +-T-+ +-T-+ - * | | | | | - * '+' | | '-' '-' - * +-+---------+---------+---------+---------+-+ - * | Calculated net | - * +-------------------------------------------+ - * - * SPICE uses the following basic two terminal device: - * - * (k) - * +-----T-----+ - * | | | - * | +--+--+ | - * | | | | - * | R | | - * | R | | - * | R I | - * | | I | Device n - * | V+ I | - * | V | | - * | V- | | - * | | | | - * | +--+--+ | - * | | | - * +-----T-----+ - * (l) - * - * This is a resistance in series to a voltage source and paralleled by a - * current source. This is suitable to model voltage sources, current sources, - * resistors, capacitors, inductances and diodes. - * - * I(n,l) = - I(n,k) = ( V(k) - V - V(l) ) * (1/R(n)) + I(n) - * - * Now, the sum of all currents for a given net must be 0: - * - * Sum(n,I(n,l)) = 0 = sum(n, ( V(k) - V(n) - V(l) ) * (1/R(n)) + I(n) ) - * - * With G(n) = 1 / R(n) and sum(n, G(n)) = Gtot and k=k(n) - * - * 0 = - V(l) * Gtot + sum(n, (V(k(n)) - V(n)) * G(n) + I(n)) - * - * and with l=l(n) and fixed k - * - * 0 = -V(k) * Gtot + sum(n, ( V(l(n) + V(n) ) * G(n) - I(n)) - * - * These equations represent a linear Matrix equation (with more math). - * - * In the end the solution of the analog subsystem boils down to - * - * (G - D) * V = I - * - * with G being the conductance matrix, D a diagonal matrix with the total - * conductance on the diagonal elements, V the net voltage vector and I the - * current vector. - * - * By using solely two terminal devices, we can simplify the whole calculation - * significantly. A BJT now is a four terminal device with two terminals being - * connected internally. - * - * The system is solved using an iterative approach: - * - * G * V - D * V = I - * - * assuming V=Vn=Vo - * - * Vn = D-1 * (I - G * Vo) - * - * Each terminal thus has three properties: - * - * a) Resistance - * b) Voltage source - * c) Current source/sink - * - * Going forward, the approach can be extended e.g. to use a linear - * equation solver. - * - * The formal representation of the circuit will stay the same, thus scales. + * \file nl_base.h * */ @@ -171,45 +25,92 @@ // Type definitions // ---------------------------------------------------------------------------------------- +/*! netlist_sig_t is the type used for logic signals. */ using netlist_sig_t = std::uint_least32_t; - //============================================================ - // MACROS / New Syntax - //============================================================ +//============================================================ +// MACROS / New Syntax +//============================================================ +/*! Construct a netlist device name */ #define NETLIB_NAME(chip) nld_ ## chip #define NETLIB_OBJECT_DERIVED(name, pclass) \ class NETLIB_NAME(name) : public NETLIB_NAME(pclass) +/*! Start a netlist device class. + * Used to start defining a netlist device class. + * The simplest device without inputs or outputs would look like this: + * + * NETLIB_OBJECT(base_dummy) + * { + * public: + * NETLIB_CONSTRUCTOR(base_dummy) { } + * }; + * + * Also refer to #NETLIB_CONSTRUCTOR. + */ #define NETLIB_OBJECT(name) \ class NETLIB_NAME(name) : public device_t #define NETLIB_CONSTRUCTOR_DERIVED(cname, pclass) \ - private: family_setter_t m_famsetter; \ + private: detail::family_setter_t m_famsetter; \ public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ : NETLIB_NAME(pclass)(owner, name) -#define NETLIB_CONSTRUCTOR(cname) \ - private: family_setter_t m_famsetter; \ +/*! Used to define the constructor of a netlist device. + * Use this to define the constructor of a netlist device. Please refer to + * #NETLIB_OBJECT for an example. + */ +#define NETLIB_CONSTRUCTOR(cname) \ + private: detail::family_setter_t m_famsetter; \ public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ : device_t(owner, name) + /*! Used to define the destructor of a netlist device. + * The use of a destructor for netlist device should normally not be necessary. + */ #define NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)() -#define NETLIB_CONSTRUCTOR_EX(cname, ...) \ - private: family_setter_t m_famsetter; \ + /*! Define an extended constructor and add further parameters to it. + * The macro allows to add further parameters to a device constructor. This is + * normally used for sub-devices and system devices only. + */ +#define NETLIB_CONSTRUCTOR_EX(cname, ...) \ + private: detail::family_setter_t m_famsetter; \ public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name, __VA_ARGS__) \ : device_t(owner, name) -#define NETLIB_DYNAMIC() \ + /*! Add this to a device definition to mark the device as dynamic. + * If this is added to device definition the device is treated as an analog + * dynamic device, i.e. #NETLIB_UPDATE_TERMINALSI is called on a each step + * of the Newton-Raphson step of solving the linear equations. + */ +#define NETLIB_DYNAMIC() \ public: virtual bool is_dynamic() const override { return true; } -#define NETLIB_TIMESTEP() \ + /*! Add this to a device definition to mark the device as a time-stepping device + * and add code. + * If this is added to device definition the device is treated as an analog + * time-stepping device. Currently, only the capacitor device uses this. An other + * example would be an inductor device. + * + * Example: + * + * NETLIB_TIMESTEP() + * { + * // Gpar should support convergence + * const nl_double G = m_C.Value() / step + m_GParallel; + * const nl_double I = -G * deltaV(); + * set(G, 0.0, I); + * } + * + */ +#define NETLIB_TIMESTEP() \ public: virtual bool is_timestep() const override { return true; } \ public: virtual void step_time(const nl_double step) override -#define NETLIB_UPDATE_AFTER_PARAM_CHANGE() \ +#define NETLIB_UPDATE_AFTER_PARAM_CHANGE() \ public: virtual bool needs_update_after_param_change() const override { return true; } #define NETLIB_FAMILY(family) , m_famsetter(*this, family) @@ -266,14 +167,33 @@ namespace netlist class NETLIB_NAME(base_d_to_a_proxy); } + namespace detail { + class object_t; + class device_object_t; + struct netlist_ref; + class core_terminal_t; + struct family_setter_t; + class queue_t; + class net_t; + } + //============================================================ // Exceptions //============================================================ + /*! Generic netlist expection. + * The exception is used in all events which are considered fatal. + */ class nl_exception : public plib::pexception { public: - explicit nl_exception(const pstring text) : plib::pexception(text) { } + /*! Constructor. + * Allows a descriptive text to be assed to the exception + */ + explicit nl_exception(const pstring text //!< text to be passed + ) + : plib::pexception(text) { } + /*! Copy constructor. */ nl_exception(const nl_exception &e) : plib::pexception(e) { } virtual ~nl_exception() noexcept {} }; @@ -287,16 +207,15 @@ namespace netlist class core_device_t; class device_t; - // ----------------------------------------------------------------------------- - // model_map_t - // ----------------------------------------------------------------------------- - + /*! Type of the model map used. + * This is used to hold all #Models in an unordered map + */ using model_map_t = std::unordered_map<pstring, pstring>; - // ----------------------------------------------------------------------------- - // logic_family_t - // ----------------------------------------------------------------------------- - + /*! Logic families descriptors are used create proxy devices. + * The logic family describe the analog capabilities of logic devices, + * inputs and outputs. + */ class logic_family_desc_t { public: @@ -305,14 +224,25 @@ namespace netlist virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; - nl_double m_low_thresh_V; - nl_double m_high_thresh_V; - nl_double m_low_V; - nl_double m_high_V; - nl_double m_R_low; - nl_double m_R_high; + nl_double m_low_thresh_V; //!< low input threshhold. If the input voltage is below this value, a "0" input is signalled + nl_double m_high_thresh_V; //!< high input threshhold. If the input voltage is above this value, a "0" input is signalled + nl_double m_low_V; //!< low output voltage. This voltage is output if the ouput is "0" + nl_double m_high_V; //!< high output voltage. This voltage is output if the ouput is "1" + nl_double m_R_low; //!< low output resistance. Value of series resistor used for low output + nl_double m_R_high; //!< high output resistance. Value of series resistor used for high output }; + /*! Base class for devices, terminals, outputs and inputs which support + * logic families. + * This class is a storage container to store the logic family for a + * netlist object. You will not directly use it. Please refer to + * #NETLIB_FAMILY to learn how to define a logic family for a device. + * + * All terminals inherit the family description from the device + * The default is the ttl family, but any device can override the family. + * For individual terminals, the family can be overwritten as well. + * + */ class logic_family_t { public: @@ -327,43 +257,58 @@ namespace netlist const logic_family_desc_t *m_logic_family; }; - /* Terminals inherit the family description from the device - * The default is the ttl family, but any device can override the family. - * For individual terminals, these can be overwritten as well. + const logic_family_desc_t *family_TTL(); //*!< logic family for TTL devices. + const logic_family_desc_t *family_CD4XXX(); //*!< logic family for CD4XXX CMOS devices. + + /*! A persistent variable template. + * Use the state_var template to define a variable whose value is saved. + * Within a device definition use * - * Only devices of type GENERIC should have a family description entry + * NETLIB_OBJECT(abc) + * { + * NETLIB_CONSTRUCTOR(abc) + * , m_var(*this, "myvar", 0) + * ... + * state_var<unsigned> m_var; + * } */ - - const logic_family_desc_t *family_TTL(); - const logic_family_desc_t *family_CD4XXX(); - - - // ----------------------------------------------------------------------------- - // State variables - use to preserve state - // ----------------------------------------------------------------------------- - template <typename T> struct state_var { public: template <typename O> - state_var(O &owner, const pstring name, const T &value); + //! Constructor. + state_var(O &owner, //!< owner must have a netlist() method. + const pstring name, //!< identifier/name for this state variable + const T &value //!< Initial value after construction + ); + //! Copy Constructor. state_var(const state_var &rhs) NOEXCEPT = default; + //! Move Constructor. state_var(state_var &&rhs) NOEXCEPT = default; + //! Assignment operator to assign value of a state var. state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; } + //! Assignment operator to assign value of type T. state_var &operator=(const T rhs) { m_value = rhs; return *this; } + //! Return value of state variable. operator T & () { return m_value; } + //! Return value of state variable. T & operator()() { return m_value; } + //! Return const value of state variable. operator const T & () const { return m_value; } + //! Return const value of state variable. const T & operator()() const { return m_value; } - T * ptr() { return &m_value; } const T * ptr() const { return &m_value; } private: T m_value; }; + /*! A persistent array template. + * Use this state_var template to define an array whose contents are saved. + * Please refer to \ref state_var. + */ template <typename T, std::size_t N> struct state_var<T[N]> { @@ -383,42 +328,55 @@ namespace netlist // State variables - predefined and c++11 non-optioanl // ----------------------------------------------------------------------------- + /*! predefined state variable type for uint_fast8_t */ using state_var_u8 = state_var<std::uint_fast8_t>; + /*! predefined state variable type for int_fast8_t */ using state_var_s8 = state_var<std::int_fast8_t>; + /*! predefined state variable type for uint_fast32_t */ using state_var_u32 = state_var<std::uint_fast32_t>; + /*! predefined state variable type for int_fast32_t */ using state_var_s32 = state_var<std::int_fast32_t>; // ----------------------------------------------------------------------------- // object_t // ----------------------------------------------------------------------------- - - class object_t + /*! The base class for netlist devices, terminals and parameters. + * + * This class serves as the base class for all device, terminal and + * objects. It provides new and delete operators to supported e.g. pooled + * memory allocation to enhance locality. Please refer to \ref USE_MEMPOOL as + * well. + */ + class detail::object_t { P_PREVENT_COPYING(object_t) public: - object_t(const pstring &aname); + /*! Constructor. + * + * Every class derived from the object_t class must have a name. + */ + object_t(const pstring &aname /*!< string containing name of the object */); ~object_t(); + /*! return name of the object + * + * \returns name of the object. + */ const pstring &name() const; - //netlist_t & m_netlist; - //netlist_t & netlist() { return m_netlist; } - //const netlist_t & netlist() const { return m_netlist; } - - private: - pstring m_name; - - public: void * operator new (size_t size, void *ptr) { return ptr; } void operator delete (void *ptr, void *) { } void * operator new (size_t size); void operator delete (void * mem); + + private: + pstring m_name; }; - struct netlist_ref + struct detail::netlist_ref { netlist_ref(netlist_t &nl) : m_netlist(nl) { } @@ -434,28 +392,53 @@ namespace netlist // device_object_t // ----------------------------------------------------------------------------- - class device_object_t : public object_t + /*! Base class for all objects being owned by a device. + * + * Serves as the base class of all objects being owned by a device. + * + */ + class detail::device_object_t : public detail::object_t { P_PREVENT_COPYING(device_object_t) public: + /*! Enum specifying the type of object */ enum type_t { - TERMINAL = 0, - INPUT = 1, - OUTPUT = 2, - PARAM = 3, + TERMINAL = 0, /*!< object is an analog terminal */ + INPUT = 1, /*!< object is an input */ + OUTPUT = 2, /*!< object is an output */ + PARAM = 3, /*!< object is a parameter */ }; - device_object_t(core_device_t &dev, const pstring &aname, const type_t atype); + /*! Constructor. + * + * \param dev device owning the object. + * \param name string holding the name of the device + * \param type type of this object. + */ + device_object_t(core_device_t &dev, const pstring &name, const type_t type); + /*! returns reference to owning device. + * \returns reference to owning device. + */ core_device_t &device() const { return m_device; } + /*! The object type. + * \returns type of the object + */ type_t type() const { return m_type; } - bool is_type(const type_t atype) const { return (m_type == atype); } + /*! Checks if object is of specified type. + * \param type type to check object against. + * \returns true if object is of specified type else false. + */ + bool is_type(const type_t type) const { return (m_type == type); } + /*! The netlist owning the owner of this object. + * \returns reference to netlist object. + */ netlist_t &netlist(); private: core_device_t & m_device; - const type_t m_type; + const type_t m_type; }; @@ -463,7 +446,7 @@ namespace netlist // core_terminal_t // ----------------------------------------------------------------------------- - class core_terminal_t : public device_object_t, public plib::linkedlist_t<core_terminal_t>::element_t + class detail::core_terminal_t : public device_object_t, public plib::linkedlist_t<core_terminal_t>::element_t { P_PREVENT_COPYING(core_terminal_t) public: @@ -513,7 +496,7 @@ namespace netlist // analog_t // ----------------------------------------------------------------------------- - class analog_t : public core_terminal_t + class analog_t : public detail::core_terminal_t { public: @@ -537,7 +520,7 @@ namespace netlist terminal_t(core_device_t &dev, const pstring &aname); - terminal_t *m_otherterm; + nl_double operator ()() const; void set(const nl_double G) { @@ -570,6 +553,8 @@ namespace netlist m_Idr1 = Idr; } + terminal_t *m_otherterm; + private: void set_ptr(nl_double *ptr, const nl_double val) { @@ -590,7 +575,7 @@ namespace netlist // logic_t // ----------------------------------------------------------------------------- - class logic_t : public core_terminal_t, public logic_family_t + class logic_t : public detail::core_terminal_t, public logic_family_t { public: logic_t(core_device_t &dev, const pstring &aname, const type_t atype) @@ -623,6 +608,12 @@ namespace netlist netlist_sig_t Q() const; + netlist_sig_t operator()() const + { + nl_assert(state() != STATE_INP_PASSIVE); + return Q(); + } + void inactivate(); void activate(); void activate_hl(); @@ -634,11 +625,27 @@ namespace netlist // analog_input_t // ----------------------------------------------------------------------------- + /*! terminal providing analog input voltage. + * + * This terminal class provides a voltage measurement. The conductance against + * ground is infinite. + */ class analog_input_t : public analog_t { public: - analog_input_t(core_device_t &dev, const pstring &aname); + /*! Constructor */ + analog_input_t(core_device_t &dev, /*!< owning device */ + const pstring &aname /*!< name of terminal */ + ); + + /*! returns voltage at terminal. + * \returns voltage at terminal. + */ + nl_double operator()() const { return Q_Analog(); } + /*! returns voltage at terminal. + * \returns voltage at terminal. + */ nl_double Q_Analog() const; }; @@ -647,7 +654,9 @@ namespace netlist // net_t // ----------------------------------------------------------------------------- - class net_t : public object_t, public netlist_ref + class detail::net_t : + public detail::object_t, + public detail::netlist_ref { P_PREVENT_COPYING(net_t) public: @@ -707,12 +716,12 @@ namespace netlist }; - class logic_net_t : public net_t + class logic_net_t : public detail::net_t { P_PREVENT_COPYING(logic_net_t) public: - logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); + logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); virtual ~logic_net_t() { } netlist_sig_t Q() const { return m_cur_Q; } @@ -748,14 +757,14 @@ namespace netlist }; - class analog_net_t : public net_t + class analog_net_t : public detail::net_t { P_PREVENT_COPYING(analog_net_t) public: using list_t = std::vector<analog_net_t *>; - analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); + analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); virtual ~analog_net_t() { } @@ -786,7 +795,7 @@ namespace netlist void initial(const netlist_sig_t val); - void set_Q(const netlist_sig_t newQ, const netlist_time delay) NOEXCEPT + void push(const netlist_sig_t newQ, const netlist_time delay) NOEXCEPT { m_my_net.set_Q(newQ, delay); // take the shortcut } @@ -799,13 +808,13 @@ namespace netlist { P_PREVENT_COPYING(analog_output_t) public: - analog_output_t(core_device_t &dev, const pstring &aname); + void push(const nl_double val) { set_Q(val); } void initial(const nl_double val); - void set_Q(const nl_double newQ); private: + void set_Q(const nl_double newQ); analog_net_t m_my_net; }; @@ -813,7 +822,7 @@ namespace netlist // param_t // ----------------------------------------------------------------------------- - class param_t : public device_object_t + class param_t : public detail::device_object_t { P_PREVENT_COPYING(param_t) public: @@ -842,13 +851,13 @@ namespace netlist public: param_template_t(device_t &device, const pstring name, const C val); - operator const C() const { return Value(); } + const C operator()() const { return Value(); } void setTo(const C ¶m); void initial(const C &val) { m_param = val; } - C Value() const { return m_param; } protected: + C Value() const { return m_param; } virtual void changed() { } C m_param; private: @@ -883,7 +892,10 @@ namespace netlist // core_device_t // ----------------------------------------------------------------------------- - class core_device_t : public object_t, public logic_family_t, public netlist_ref + class core_device_t : + public detail::object_t, + public logic_family_t, + public detail::netlist_ref { P_PREVENT_COPYING(core_device_t) public: @@ -929,18 +941,6 @@ namespace netlist void do_reset() { reset(); } void set_hint_deactivate(bool v) { m_hint_deactivate = v; } - netlist_sig_t INPLOGIC_PASSIVE(logic_input_t &inp); - netlist_sig_t INPLOGIC(const logic_input_t &inp) const - { - nl_assert(inp.state() != logic_t::STATE_INP_PASSIVE); - return inp.Q(); - } - - void OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time delay) NOEXCEPT; - nl_double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); } - nl_double TERMANALOG(const terminal_t &term) const { return term.net().Q_Analog(); } - void OUTANALOG(analog_output_t &out, const nl_double val) { out.set_Q(val); } - /* stats */ nperftime_t m_stat_total_time; nperfcount_t m_stat_call_count; @@ -1001,12 +1001,12 @@ namespace netlist } #endif - void register_subalias(const pstring &name, core_terminal_t &term); + void register_subalias(const pstring &name, detail::core_terminal_t &term); void register_subalias(const pstring &name, const pstring &aliased); void connect_late(const pstring &t1, const pstring &t2); - void connect_late(core_terminal_t &t1, core_terminal_t &t2); - void connect_post_start(core_terminal_t &t1, core_terminal_t &t2); + void connect_late(detail::core_terminal_t &t1, detail::core_terminal_t &t2); + void connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2); protected: NETLIB_UPDATEI() { } @@ -1019,7 +1019,7 @@ namespace netlist // family_setter_t // ----------------------------------------------------------------------------- - struct family_setter_t + struct detail::family_setter_t { family_setter_t() { } family_setter_t(core_device_t &dev, const char *desc); @@ -1040,10 +1040,11 @@ namespace netlist // queue_t // ----------------------------------------------------------------------------- - class queue_t : public timed_queue<net_t *, netlist_time>, - public object_t, - public netlist_ref, - public plib::state_manager_t::callback_t + class detail::queue_t : + public timed_queue<net_t *, netlist_time>, + public detail::object_t, + public detail::netlist_ref, + public plib::state_manager_t::callback_t { public: explicit queue_t(netlist_t &nl); @@ -1056,7 +1057,7 @@ namespace netlist private: struct names_t { char m_buf[64]; }; - int m_qsize; + std::size_t m_qsize; std::vector<netlist_time::internal_type> m_times; std::vector<names_t> m_names; }; @@ -1068,7 +1069,6 @@ namespace netlist class netlist_t : public plib::plog_dispatch_intf { - friend class setup_t; P_PREVENT_COPYING(netlist_t) public: @@ -1080,15 +1080,15 @@ namespace netlist void start(); void stop(); - const queue_t &queue() const { return m_queue; } - queue_t &queue() { return m_queue; } + const detail::queue_t &queue() const { return m_queue; } + detail::queue_t &queue() { return m_queue; } const netlist_time time() const { return m_time; } devices::NETLIB_NAME(solver) *solver() const { return m_solver; } devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; } nl_double gmin() const; - void push_to_queue(net_t &out, const netlist_time attime) NOEXCEPT; - void remove_from_queue(net_t &out); + void push_to_queue(detail::net_t &out, const netlist_time attime) NOEXCEPT; + void remove_from_queue(detail::net_t &out); void process_queue(const netlist_time &delta); void abort_current_queue_slice() { m_queue.retime(m_time, nullptr); } @@ -1098,10 +1098,9 @@ namespace netlist void set_setup(setup_t *asetup) { m_setup = asetup; } setup_t &setup() { return *m_setup; } - void register_dev(plib::owned_ptr<device_t> dev); - net_t *find_net(const pstring &name); + detail::net_t *find_net(const pstring &name); template<class device_class> std::vector<device_class *> get_device_list() @@ -1143,7 +1142,7 @@ namespace netlist { this->state().save_item(static_cast<void *>(&owner), state, pstring(owner.name()) + "." + stname); } - template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const int count) + template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const std::size_t count) { this->state().save_state_ptr(static_cast<void *>(&owner), pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state); } @@ -1154,21 +1153,18 @@ namespace netlist void print_stats() const; - std::vector<plib::owned_ptr<core_device_t>> m_devices; - + std::vector<plib::owned_ptr<core_device_t>> m_devices; /* sole use is to manage lifetime of net objects */ - std::vector<plib::owned_ptr<net_t>> m_nets; - + std::vector<plib::owned_ptr<detail::net_t>> m_nets; /* sole use is to manage lifetime of family objects */ std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache; private: - plib::state_manager_t m_state; + plib::state_manager_t m_state; /* mostly rw */ - netlist_time m_time; - queue_t m_queue; + netlist_time m_time; + detail::queue_t m_queue; - nperftime_t m_stat_mainloop; /* mostly ro */ devices::NETLIB_NAME(mainclock) * m_mainclock; @@ -1176,15 +1172,16 @@ namespace netlist devices::NETLIB_NAME(gnd) * m_gnd; devices::NETLIB_NAME(netlistparams) *m_params; - pstring m_name; - setup_t *m_setup; - plib::plog_base<NL_DEBUG> m_log; - plib::dynlib *m_lib; // external lib needs to be loaded as long as netlist exists + pstring m_name; + setup_t * m_setup; + plib::plog_base<NL_DEBUG> m_log; + plib::dynlib * m_lib; // external lib needs to be loaded as long as netlist exists // performance - nperfcount_t m_perf_out_processed; - nperfcount_t m_perf_inp_processed; - nperfcount_t m_perf_inp_active; + nperftime_t m_stat_mainloop; + nperfcount_t m_perf_out_processed; + nperfcount_t m_perf_inp_processed; + nperfcount_t m_perf_inp_active; }; // ----------------------------------------------------------------------------- @@ -1223,22 +1220,22 @@ namespace netlist } } - inline bool core_terminal_t::is_logic() const + inline bool detail::core_terminal_t::is_logic() const { return dynamic_cast<const logic_t *>(this) != nullptr; } - inline bool core_terminal_t::is_analog() const + inline bool detail::core_terminal_t::is_analog() const { return dynamic_cast<const analog_t *>(this) != nullptr; } - inline bool net_t::is_logic() const + inline bool detail::net_t::is_logic() const { return dynamic_cast<const logic_net_t *>(this) != nullptr; } - inline bool net_t::is_analog() const + inline bool detail::net_t::is_analog() const { return dynamic_cast<const analog_net_t *>(this) != nullptr; } @@ -1279,7 +1276,7 @@ namespace netlist } } - inline void net_t::push_to_queue(const netlist_time delay) NOEXCEPT + inline void detail::net_t::push_to_queue(const netlist_time delay) NOEXCEPT { if (!is_queued() && (num_cons() != 0)) { @@ -1292,7 +1289,7 @@ namespace netlist } } - inline void net_t::reschedule_in_queue(const netlist_time delay) NOEXCEPT + inline void detail::net_t::reschedule_in_queue(const netlist_time delay) NOEXCEPT { if (is_queued()) netlist().remove_from_queue(*this); @@ -1315,6 +1312,8 @@ namespace netlist return static_cast<analog_net_t &>(core_terminal_t::net()); } + inline nl_double terminal_t::operator ()() const { return net().Q_Analog(); } + inline logic_net_t & logic_t::net() { return *static_cast<logic_net_t *>(&core_terminal_t::net()); @@ -1345,21 +1344,16 @@ namespace netlist } } - inline void netlist_t::push_to_queue(net_t &out, const netlist_time attime) NOEXCEPT + inline void netlist_t::push_to_queue(detail::net_t &out, const netlist_time attime) NOEXCEPT { m_queue.push(attime, &out); } - inline void netlist_t::remove_from_queue(net_t &out) + inline void netlist_t::remove_from_queue(detail::net_t &out) { m_queue.remove(&out); } - inline void core_device_t::OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time delay) NOEXCEPT - { - out.set_Q(val, delay); - } - template <typename T> template <typename O> state_var<T>::state_var(O &owner, const pstring name, const T &value) @@ -1376,7 +1370,7 @@ namespace netlist m_value[i] = value; } - inline netlist_t &device_object_t::netlist() + inline netlist_t &detail::device_object_t::netlist() { return m_device.netlist(); } diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index d7a024d100a..a2fe70b5320 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -1,7 +1,8 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/* - * nlconfig.h +/*! + * + * \file nl_config.h * */ @@ -75,7 +76,15 @@ // GENERAL //============================================================ -#define NL_USE_MEMPOOL (0) +/*! Make use of a memory pool for performance related objects. + * + * Set to 1 to compile netlist with memory allocations from a + * linear memory pool. This is based of the assumption that + * due to enhanced locality there will be less cache misses. + * Your mileage may vary. + * + */ +#define USE_MEMPOOL (1) #define USE_TRUTHTABLE (1) //============================================================ diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h index 5923ebdd10c..a6546e32d52 100644 --- a/src/lib/netlist/nl_dice_compat.h +++ b/src/lib/netlist/nl_dice_compat.h @@ -230,7 +230,7 @@ inline int CAPACITOR_tc_lh(const double c, const double r) NET_C(GND, name ## _C.2) #else // fast, might work -#define CHIP_CAPACITOR(name, pdesc) \ +#define CHIP_CAPACITOR(name, pdesc) \ RES(name ## _C, RES_K(1000)) \ ALIAS(name.1, name ## _C.1 ) \ ALIAS(name.2, name ## _C.1) \ diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index fee6d2272e9..f1d3281aa81 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -53,10 +53,12 @@ void factory_list_t::error(const pstring &s) base_factory_t * factory_list_t::factory_by_name(const pstring &devname) { for (auto & e : *this) + { if (e->name() == devname) return e.get(); + } - m_setup.log().fatal("Class {1} not found!\n", devname); + m_setup.log().fatal("Class <{1}> not found!\n", devname); return nullptr; // appease code analysis } diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 0f5e2c5669e..84914d67450 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -117,7 +117,7 @@ namespace netlist // save state support & mame disasm const entry_t *listptr() const { return &m_list[1]; } - std::size_t size() const { return m_end - &m_list[1]; } + std::size_t size() const { return static_cast<std::size_t>(m_end - &m_list[1]); } const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; } private: diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index c0b0b56bdf1..6760873a4af 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -152,9 +152,9 @@ void parser_t::net_truthtable_start() { pstring name = get_identifier(); require_token(m_tok_comma); - unsigned ni = get_number_long(); + long ni = get_number_long(); require_token(m_tok_comma); - unsigned no = get_number_long(); + long no = get_number_long(); require_token(m_tok_comma); pstring def_param = get_string(); require_token(m_tok_param_right); @@ -162,8 +162,8 @@ void parser_t::net_truthtable_start() netlist::tt_desc desc; desc.classname = name; desc.name = name; - desc.ni = ni; - desc.no = no; + desc.ni = static_cast<unsigned long>(ni); + desc.no = static_cast<unsigned long>(no); desc.def_param = "+" + def_param; desc.family = ""; @@ -317,8 +317,8 @@ void parser_t::dippins() } if ((pins.size() % 2) == 1) error("You must pass an equal number of pins to DIPPINS"); - unsigned n = pins.size(); - for (unsigned i = 0; i < n / 2; i++) + std::size_t n = pins.size(); + for (std::size_t i = 0; i < n / 2; i++) { m_setup.register_alias(plib::pfmt("{1}")(i+1), pins[i*2]); m_setup.register_alias(plib::pfmt("{1}")(n-i), pins[i*2 + 1]); diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 8aa30c9d945..8048b7db46a 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -138,8 +138,8 @@ bool setup_t::device_exists(const pstring name) const void setup_t::register_model(const pstring &model_in) { - int pos = model_in.find(" "); - if (pos < 0) + auto pos = model_in.find(" "); + if (pos == model_in.end()) log().fatal("Unable to parse model: {1}", model_in); pstring model = model_in.left(pos).trim().ucase(); pstring def = model_in.substr(pos + 1).trim(); @@ -165,15 +165,15 @@ void setup_t::register_dippins_arr(const pstring &terms) plib::pstring_vector_t list(terms,", "); if (list.size() == 0 || (list.size() % 2) == 1) log().fatal("You must pass an equal number of pins to DIPPINS"); - unsigned n = list.size(); - for (unsigned i = 0; i < n / 2; i++) + std::size_t n = list.size(); + for (std::size_t i = 0; i < n / 2; i++) { register_alias(plib::pfmt("{1}")(i+1), list[i * 2]); register_alias(plib::pfmt("{1}")(n-i), list[i * 2 + 1]); } } -pstring setup_t::objtype_as_str(device_object_t &in) const +pstring setup_t::objtype_as_str(detail::device_object_t &in) const { switch (in.type()) { @@ -187,7 +187,7 @@ pstring setup_t::objtype_as_str(device_object_t &in) const return "PARAM"; } // FIXME: noreturn - log().fatal("Unknown object type {1}\n", (unsigned) in.type()); + log().fatal("Unknown object type {1}\n", static_cast<unsigned>(in.type())); return "Error"; } @@ -214,7 +214,7 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) double vald = 0; if (sscanf(val.cstr(), "%lf", &vald) != 1) log().fatal("Invalid number conversion {1} : {2}\n", name, val); - static_cast<param_int_t &>(param).initial((int) vald); + static_cast<param_int_t &>(param).initial(static_cast<int>(vald)); } break; case param_t::STRING: @@ -224,14 +224,14 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) } break; //default: - // log().fatal("Parameter is not supported {1} : {2}\n", name, val); + // log().fatal("Parameter is not supported {1} : {2}\n", name, val); } } if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) log().fatal("Error adding parameter {1} to parameter list\n", name); } -void setup_t::register_term(core_terminal_t &term) +void setup_t::register_term(detail::core_terminal_t &term) { if (!m_terminals.insert({term.name(), &term}).second) log().fatal("Error adding {1} {2} to terminal list\n", objtype_as_str(term), term.name()); @@ -351,7 +351,7 @@ const pstring setup_t::resolve_alias(const pstring &name) const return ret; } -core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) +detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) { const pstring &tname = resolve_alias(terminal_in); auto ret = m_terminals.find(tname); @@ -362,7 +362,7 @@ core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool require ret = m_terminals.find(tname + ".Q"); } - core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); + detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); if (term == nullptr && required) log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname); @@ -371,12 +371,13 @@ core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool require return term; } -core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, device_object_t::type_t atype, bool required) +detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, + detail::device_object_t::type_t atype, bool required) { const pstring &tname = resolve_alias(terminal_in); auto ret = m_terminals.find(tname); /* look for default */ - if (ret == m_terminals.end() && atype == device_object_t::OUTPUT) + if (ret == m_terminals.end() && atype == detail::device_object_t::OUTPUT) { /* look for ".Q" std output */ ret = m_terminals.find(tname + ".Q"); @@ -384,7 +385,7 @@ core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, device_objec if (ret == m_terminals.end() && required) log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname); - core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); + detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); if (term != nullptr && term->type() != atype) { @@ -413,7 +414,7 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required) const } // FIXME avoid dynamic cast here -devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out) +devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) { nl_assert(out.is_logic()); @@ -450,7 +451,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out) return proxy; } -void setup_t::connect_input_output(core_terminal_t &in, core_terminal_t &out) +void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out) { if (out.is_analog() && in.is_logic()) { @@ -483,7 +484,7 @@ void setup_t::connect_input_output(core_terminal_t &in, core_terminal_t &out) } -void setup_t::connect_terminal_input(terminal_t &term, core_terminal_t &inp) +void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp) { if (inp.is_analog()) { @@ -514,7 +515,7 @@ void setup_t::connect_terminal_input(terminal_t &term, core_terminal_t &inp) } } -void setup_t::connect_terminal_output(terminal_t &in, core_terminal_t &out) +void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &out) { if (out.is_analog()) { @@ -538,7 +539,7 @@ void setup_t::connect_terminal_output(terminal_t &in, core_terminal_t &out) } } -void setup_t::connect_terminals(core_terminal_t &t1, core_terminal_t &t2) +void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { if (t1.has_net() && t2.has_net()) { @@ -566,7 +567,7 @@ void setup_t::connect_terminals(core_terminal_t &t1, core_terminal_t &t2) } } -static core_terminal_t &resolve_proxy(core_terminal_t &term) +static detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term) { if (term.is_logic()) { @@ -577,7 +578,7 @@ static core_terminal_t &resolve_proxy(core_terminal_t &term) return term; } -bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2) +bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { bool ret = false; if (t1.has_net()) @@ -588,7 +589,7 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2) { for (auto & t : t1.net().m_core_terms) { - if (t->is_type(core_terminal_t::TERMINAL)) + if (t->is_type(detail::core_terminal_t::TERMINAL)) ret = connect(t2, *t); if (ret) break; @@ -603,7 +604,7 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2) { for (auto & t : t2.net().m_core_terms) { - if (t->is_type(core_terminal_t::TERMINAL)) + if (t->is_type(detail::core_terminal_t::TERMINAL)) ret = connect(t1, *t); if (ret) break; @@ -615,46 +616,46 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2) -bool setup_t::connect(core_terminal_t &t1_in, core_terminal_t &t2_in) +bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in) { log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name()); - core_terminal_t &t1 = resolve_proxy(t1_in); - core_terminal_t &t2 = resolve_proxy(t2_in); + detail::core_terminal_t &t1 = resolve_proxy(t1_in); + detail::core_terminal_t &t2 = resolve_proxy(t2_in); bool ret = true; - if (t1.is_type(core_terminal_t::OUTPUT) && t2.is_type(core_terminal_t::INPUT)) + if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::INPUT)) { if (t2.has_net() && t2.net().isRailNet()) log().fatal("Input {1} already connected\n", t2.name()); connect_input_output(t2, t1); } - else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::OUTPUT)) + else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::OUTPUT)) { if (t1.has_net() && t1.net().isRailNet()) log().fatal("Input {1} already connected\n", t1.name()); connect_input_output(t1, t2); } - else if (t1.is_type(core_terminal_t::OUTPUT) && t2.is_type(core_terminal_t::TERMINAL)) + else if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::TERMINAL)) { connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1); } - else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::OUTPUT)) + else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::OUTPUT)) { connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2); } - else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::TERMINAL)) + else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::TERMINAL)) { connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1); } - else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::INPUT)) + else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::INPUT)) { connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2); } - else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::TERMINAL)) + else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::TERMINAL)) { connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2)); } - else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::INPUT)) + else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::INPUT)) { ret = connect_input_input(t1, t2); } @@ -682,8 +683,8 @@ void setup_t::resolve_inputs() { const pstring t1s = li->first; const pstring t2s = li->second; - core_terminal_t *t1 = find_terminal(t1s); - core_terminal_t *t2 = find_terminal(t2s); + detail::core_terminal_t *t1 = find_terminal(t1s); + detail::core_terminal_t *t2 = find_terminal(t2s); if (connect(*t1, *t2)) li = m_links.erase(li); @@ -720,7 +721,7 @@ void setup_t::resolve_inputs() log().verbose("looking for terminals not connected ..."); for (auto & i : m_terminals) { - core_terminal_t *term = i.second; + detail::core_terminal_t *term = i.second; if (!term->has_net() && dynamic_cast< devices::NETLIB_NAME(dummy_input) *>(&term->device()) != nullptr) log().warning("Found dummy terminal {1} without connections", term->name()); else if (!term->has_net()) @@ -777,61 +778,7 @@ void setup_t::start_devices() } } - /* make sure the solver and parameters are started first! */ - - for (auto & e : m_device_factory) - { - if ( factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second) - || factory().is_class<devices::NETLIB_NAME(solver)>(e.second) - || factory().is_class<devices::NETLIB_NAME(gnd)>(e.second) - || factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) - { - auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first)); - netlist().register_dev(std::move(dev)); - } - } - - log().debug("Searching for mainclock and solver ...\n"); - - netlist().m_mainclock = netlist().get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock"); - netlist().m_solver = netlist().get_single_device<devices::NETLIB_NAME(solver)>("solver"); - netlist().m_gnd = netlist().get_single_device<devices::NETLIB_NAME(gnd)>("gnd"); - netlist().m_params = netlist().get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); - - /* create devices */ - - for (auto & e : m_device_factory) - { - if ( !factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second) - && !factory().is_class<devices::NETLIB_NAME(solver)>(e.second) - && !factory().is_class<devices::NETLIB_NAME(gnd)>(e.second) - && !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) - { - auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first)); - netlist().register_dev(std::move(dev)); - } - } - - bool use_deactivate = (netlist().m_params->m_use_deactivate.Value() ? true : false); - - for (auto &d : netlist().m_devices) - { - if (use_deactivate) - { - auto p = m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE"); - if (p != m_param_values.end()) - { - //FIXME: Error checking - auto v = p->second.as_long(); - d->set_hint_deactivate(!v); - } - } - else - d->set_hint_deactivate(false); - } - netlist().start(); - } plib::plog_base<NL_DEBUG> &setup_t::log() @@ -901,13 +848,13 @@ static pstring model_string(model_map_t &map) void setup_t::model_parse(const pstring &model_in, model_map_t &map) { pstring model = model_in; - int pos = 0; + pstring::iterator pos(nullptr); pstring key; while (true) { pos = model.find("("); - if (pos >= 0) break; + if (pos != model.end()) break; key = model.ucase(); auto i = m_models.find(key); @@ -931,13 +878,14 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map) pstring remainder=model.substr(pos+1).trim(); if (!remainder.endsWith(")")) log().fatal("Model error {1}\n", model); - remainder = remainder.left(remainder.len() - 1); + // FIMXE: Not optimal + remainder = remainder.left(remainder.begin() + (remainder.len() - 1)); plib::pstring_vector_t pairs(remainder," ", true); for (pstring &pe : pairs) { - int pose = pe.find("="); - if (pose < 0) + auto pose = pe.find("="); + if (pose == pe.end()) log().fatal("Model error on pair {1}\n", model); map[pe.left(pose).ucase()] = pe.substr(pose+1); } @@ -962,8 +910,8 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity) pstring tmp = model_value_str(map, entity); nl_double factor = NL_FCONST(1.0); - pstring numfac = tmp.right(1); - switch (numfac.code_at(0)) + auto p = tmp.begin() + (tmp.len() - 1); + switch (*p) { case 'M': factor = 1e6; break; case 'k': factor = 1e3; break; @@ -974,11 +922,11 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity) case 'f': factor = 1e-15; break; case 'a': factor = 1e-18; break; default: - if (numfac < "0" || numfac > "9") - nl_exception(plib::pfmt("Unknown number factor <{1}> in: {2}")(numfac)(entity)); + if (*p < '0' || *p > '9') + nl_exception(plib::pfmt("Unknown number factor in: {1}")(entity)); } if (factor != NL_FCONST(1.0)) - tmp = tmp.left(tmp.len() - 1); + tmp = tmp.left(tmp.begin() + (tmp.len() - 1)); return tmp.as_double() * factor; } @@ -1013,7 +961,7 @@ bool setup_t::parse_stream(plib::pistream &istrm, const pstring &name) void setup_t::register_define(pstring defstr) { auto p = defstr.find("="); - if (p>0) + if (p != defstr.end()) register_define(defstr.left(p), defstr.substr(p+1)); else register_define(defstr, "1"); diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 85dc1eb4fd5..86de48e81ce 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -120,8 +120,8 @@ namespace netlist { pstring name; pstring classname; - unsigned ni; - unsigned no; + unsigned long ni; + unsigned long no; pstring def_param; plib::pstring_vector_t desc; pstring family; @@ -184,7 +184,7 @@ namespace netlist void register_and_set_param(pstring name, param_t ¶m); - void register_term(core_terminal_t &obj); + void register_term(detail::core_terminal_t &obj); void register_dev(const pstring &classname, const pstring &name); @@ -207,7 +207,7 @@ namespace netlist void remove_connections(const pstring attach); - bool connect(core_terminal_t &t1, core_terminal_t &t2); + bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2); bool device_exists(const pstring name) const; @@ -250,11 +250,6 @@ namespace netlist void model_parse(const pstring &model, model_map_t &map); - plib::plog_base<NL_DEBUG> &log(); - const plib::plog_base<NL_DEBUG> &log() const; - - std::vector<std::pair<pstring, base_factory_t *>> m_device_factory; - /* FIXME: truth table trampoline */ void tt_factory_create(tt_desc &desc); @@ -262,47 +257,44 @@ namespace netlist /* helper - also used by nltool */ const pstring resolve_alias(const pstring &name) const; - protected: - - private: - - core_terminal_t *find_terminal(const pstring &outname_in, bool required = true); - core_terminal_t *find_terminal(const pstring &outname_in, device_object_t::type_t atype, bool required = true); - - void connect_terminals(core_terminal_t &in, core_terminal_t &out); - void connect_input_output(core_terminal_t &in, core_terminal_t &out); - void connect_terminal_output(terminal_t &in, core_terminal_t &out); - void connect_terminal_input(terminal_t &term, core_terminal_t &inp); - bool connect_input_input(core_terminal_t &t1, core_terminal_t &t2); - - // helpers - pstring objtype_as_str(device_object_t &in) const; - - devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out); + plib::plog_base<NL_DEBUG> &log(); + const plib::plog_base<NL_DEBUG> &log() const; - netlist_t &m_netlist; + std::vector<std::pair<pstring, base_factory_t *>> m_device_factory; - public: std::unordered_map<pstring, pstring> m_alias; - std::unordered_map<pstring, param_ref_t> m_params; std::unordered_map<pstring, pstring> m_param_values; - std::unordered_map<pstring, core_terminal_t *> m_terminals; + std::unordered_map<pstring, detail::core_terminal_t *> m_terminals; + private: - std::vector<link_t> m_links; + detail::core_terminal_t *find_terminal(const pstring &outname_in, bool required = true); + detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true); - factory_list_t m_factory; + void connect_terminals(detail::core_terminal_t &in, detail::core_terminal_t &out); + void connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out); + void connect_terminal_output(terminal_t &in, detail::core_terminal_t &out); + void connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp); + bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2); + + // helpers + pstring objtype_as_str(detail::device_object_t &in) const; - std::unordered_map<pstring, pstring> m_models; + devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out); - int m_proxy_cnt; - int m_frontier_cnt; + netlist_t &m_netlist; + std::unordered_map<pstring, param_ref_t> m_params; + std::vector<link_t> m_links; + factory_list_t m_factory; + std::unordered_map<pstring, pstring> m_models; - std::stack<pstring> m_namespace_stack; - source_t::list_t m_sources; - std::vector<plib::ppreprocessor::define_t> m_defines; - std::vector<pstring> m_lib; + std::stack<pstring> m_namespace_stack; + source_t::list_t m_sources; + std::vector<plib::ppreprocessor::define_t> m_defines; + std::vector<pstring> m_lib; + unsigned m_proxy_cnt; + unsigned m_frontier_cnt; }; // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h index 974ba4c669c..bd9a12168e9 100644 --- a/src/lib/netlist/nl_time.h +++ b/src/lib/netlist/nl_time.h @@ -104,7 +104,8 @@ namespace netlist } constexpr internal_type as_raw() const { return m_time; } - constexpr double as_double() const { return (double) m_time / (double) resolution; } + constexpr double as_double() const { return static_cast<double>(m_time) + / static_cast<double>(resolution); } // for save states .... internal_type *get_internaltype_ptr() { return &m_time; } @@ -114,7 +115,7 @@ namespace netlist static constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); } static constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); } static constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); } - static constexpr ptime from_double(const double t) { return ptime((internal_type) ( t * (double) resolution), resolution); } + static constexpr ptime from_double(const double t) { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); } static constexpr ptime zero() { return ptime(0, resolution); } static constexpr ptime quantum() { return ptime(1, resolution); } diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp index ef9e42dcba5..c89c2ed7e63 100644 --- a/src/lib/netlist/plib/palloc.cpp +++ b/src/lib/netlist/plib/palloc.cpp @@ -12,7 +12,6 @@ #include "pfmtlog.h" namespace plib { - //============================================================ // Exceptions //============================================================ @@ -56,7 +55,7 @@ out_of_mem_e::out_of_mem_e(const pstring &location) // Memory pool //============================================================ -mempool::mempool(int min_alloc, int min_align) +mempool::mempool(size_t min_alloc, size_t min_align) : m_min_alloc(min_alloc), m_min_align(min_align) { } @@ -71,7 +70,7 @@ mempool::~mempool() m_blocks.clear(); } -int mempool::new_block() +size_t mempool::new_block() { block b; b.data = new char[m_min_alloc]; @@ -93,21 +92,21 @@ void *mempool::alloc(size_t size) { b.m_free -= rs; b.m_num_alloc++; - info *i = (info *) b.cur_ptr; + auto i = reinterpret_cast<info *>(b.cur_ptr); i->m_block = bn; - void *ret = (void *) (b.cur_ptr + sizeof(info)); + auto ret = reinterpret_cast<void *>(b.cur_ptr + sizeof(info)); b.cur_ptr += rs; return ret; } } { - int bn = new_block(); + size_t bn = new_block(); auto &b = m_blocks[bn]; b.m_num_alloc = 1; b.m_free = m_min_alloc - rs; - info *i = (info *) b.cur_ptr; + auto i = reinterpret_cast<info *>(b.cur_ptr); i->m_block = bn; - void *ret = (void *) (b.cur_ptr + sizeof(info)); + auto ret = reinterpret_cast<void *>(b.cur_ptr + sizeof(info)); b.cur_ptr += rs; return ret; } @@ -115,9 +114,9 @@ void *mempool::alloc(size_t size) void mempool::free(void *ptr) { - char *p = (char *) ptr; + auto p = reinterpret_cast<char *>(ptr); - info *i = (info *) (p - sizeof(info)); + auto i = reinterpret_cast<info *>(p - sizeof(info)); block *b = &m_blocks[i->m_block]; if (b->m_num_alloc == 0) fprintf(stderr, "Argh .. double free\n"); diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index cd21be0c91e..fb467fbe173 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -17,7 +17,6 @@ #include "pstring.h" namespace plib { - //============================================================ // exception base //============================================================ @@ -204,7 +203,7 @@ private: char *data; }; - int new_block(); + size_t new_block(); struct info { @@ -213,14 +212,14 @@ private: }; public: - mempool(int min_alloc, int min_align); + mempool(size_t min_alloc, size_t min_align); ~mempool(); void *alloc(size_t size); void free(void *ptr); - int m_min_alloc; - int m_min_align; + size_t m_min_alloc; + size_t m_min_align; std::vector<block> m_blocks; }; diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h index efb8cc061b5..e37cd995ab5 100644 --- a/src/lib/netlist/plib/pchrono.h +++ b/src/lib/netlist/plib/pchrono.h @@ -183,7 +183,8 @@ namespace chrono { type total() const { return m_time; } ctype count() const { return m_count; } - double as_seconds() const { return (double) total() / (double) T::per_second(); } + double as_seconds() const { return static_cast<double>(total()) + / static_cast<double>(T::per_second()); } constexpr static bool enabled = enabled_; private: diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index e29753c7a81..770a53af49d 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -20,7 +20,7 @@ namespace plib { pfmt::pfmt(const pstring &fmt) : m_str(m_str_buf), m_allocated(0), m_arg(0) { - unsigned l = fmt.blen() + 1; + std::size_t l = fmt.blen() + 1; if (l>sizeof(m_str_buf)) { m_allocated = 2 * l; @@ -32,7 +32,7 @@ pfmt::pfmt(const pstring &fmt) pfmt::pfmt(const char *fmt) : m_str(m_str_buf), m_allocated(0), m_arg(0) { - unsigned l = strlen(fmt) + 1; + std::size_t l = strlen(fmt) + 1; if (l>sizeof(m_str_buf)) { m_allocated = 2 * l; @@ -55,11 +55,11 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, . char search[10] = ""; char buf[2048]; m_arg++; - int sl = sprintf(search, "{%d:", m_arg); + std::size_t sl = static_cast<std::size_t>(sprintf(search, "{%d:", m_arg)); char *p = strstr(m_str, search); if (p == nullptr) { - sl = sprintf(search, "{%d}", m_arg); + sl = static_cast<std::size_t>(sprintf(search, "{%d}", m_arg)); p = strstr(m_str, search); if (p == nullptr) { @@ -75,8 +75,8 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, . char *p1 = strstr(p, "}"); if (p1 != nullptr) { - sl = p1 - p + 1; - strncat(fmt, p+1, p1 - p - 2); + sl = static_cast<std::size_t>(p1 - p + 1); + strncat(fmt, p+1, static_cast<std::size_t>(p1 - p - 2)); } else strcat(fmt, f); @@ -90,11 +90,11 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, . char *p1 = strstr(p, "}"); if (p1 != nullptr) { - sl = p1 - p + 1; + sl = static_cast<std::size_t>(p1 - p + 1); if (m_arg>=10) - strncat(fmt, p+4, p1 - p - 4); + strncat(fmt, p+4, static_cast<std::size_t>(p1 - p - 4)); else - strncat(fmt, p+3, p1 - p - 3); + strncat(fmt, p+3, static_cast<std::size_t>(p1 - p - 3)); } else strcat(fmt, f); @@ -113,14 +113,14 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, . } else strcat(fmt, fmt_spec); - int nl = vsprintf(buf, fmt, ap); + std::size_t nl = static_cast<std::size_t>(vsprintf(buf, fmt, ap)); if (p != nullptr) { // check room - unsigned new_size = (p - m_str) + nl + strlen(p) + 1 - sl; + std::size_t new_size = static_cast<std::size_t>(p - m_str) + nl + strlen(p) + 1 - sl; if (new_size > m_allocated) { - unsigned old_alloc = std::max(m_allocated, (unsigned) sizeof(m_str_buf)); + std::size_t old_alloc = std::max(m_allocated, sizeof(m_str_buf)); if (m_allocated < old_alloc) m_allocated = old_alloc; while (new_size > m_allocated) diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 6fa7ac55776..44397da115a 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -21,6 +21,14 @@ struct ptype_treats }; template<> +struct ptype_treats<bool> +{ + static unsigned int cast(bool x) { return static_cast<unsigned int>(x); } + static const bool is_signed = false; + static const char *size_specifier() { return ""; } +}; + +template<> struct ptype_treats<char> { static short cast(char x) { return x; } @@ -119,6 +127,7 @@ public: P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); } P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast<P &>(*this); } P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); } + P &operator ()(const pstring_t<putf8_traits> &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); } template<typename T> P &operator ()(const T x, const char *f = "") @@ -169,7 +178,7 @@ private: char *m_str; char m_str_buf[256]; - unsigned m_allocated; + std::size_t m_allocated; unsigned m_arg; }; diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index e6bc45d15eb..2060e8ec46c 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -113,11 +113,13 @@ namespace plib { } else if (arg.startsWith("-")) { - opt = getopt_short(arg.substr(1,1)); - if (arg.len() > 2) + auto p = arg.begin() + 1; + opt = getopt_short(arg.substr(p,p + 1)); + ++p; + if (p != arg.end()) { has_equal_arg = true; - opt_arg = arg.substr(2); + opt_arg = arg.substr(p); } } else @@ -204,7 +206,7 @@ namespace plib { { line += v + "|"; } - line = line.left(line.len() - 1); + line = line.left(line.begin() + (line.len() - 1)); } else line += "Value"; diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index cfa30669801..be52b27dc30 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -29,7 +29,7 @@ void ptokenizer::skipeol() { c = getc(); if (c != 13) - ungetc(); + ungetc(c); return; } c = getc(); @@ -39,24 +39,28 @@ void ptokenizer::skipeol() pstring::code_t ptokenizer::getc() { - if (m_px >= m_cur_line.len()) + if (m_unget != 0) + { + pstring::code_t c = m_unget; + m_unget = 0; + return c; + } + if (m_px == m_cur_line.end()) { m_lineno++; if (m_strm.readline(m_cur_line)) - { - if (m_cur_line.right(1) != "\n") - m_cur_line += "\n"; - m_px = 0; - } + m_px = m_cur_line.begin(); else return 0; + return '\n'; } - return m_cur_line.code_at(m_px++); + pstring::code_t c = *(m_px++); + return c; } -void ptokenizer::ungetc() +void ptokenizer::ungetc(pstring::code_t c) { - m_px--; + m_unget = c; } void ptokenizer::require_token(const token_id_t &token_num) @@ -68,7 +72,11 @@ void ptokenizer::require_token(const token_t tok, const token_id_t &token_num) { if (!tok.is(token_num)) { - error(pfmt("Expected token <{1}> got <{2}>")(m_tokens[token_num.id()])(tok.str()) ); + pstring val(""); + for (auto &i : m_tokens) + if (i.second.id() == token_num.id()) + val = i.first; + error(pfmt("Expected token <{1}> got <{2}>")(val)(tok.str()) ); } } @@ -163,7 +171,7 @@ ptokenizer::token_t ptokenizer::get_token_internal() { /* skip ws */ pstring::code_t c = getc(); - while (m_whitespace.find(c)>=0) + while (m_whitespace.find(c) != m_whitespace.end()) { c = getc(); if (eof()) @@ -171,7 +179,7 @@ ptokenizer::token_t ptokenizer::get_token_internal() return token_t(ENDOFFILE); } } - if (m_number_chars_start.find(c)>=0) + if (m_number_chars_start.find(c) != m_number_chars_start.end()) { /* read number while we receive number or identifier chars * treat it as an identifier when there are identifier chars in it @@ -180,32 +188,30 @@ ptokenizer::token_t ptokenizer::get_token_internal() token_type ret = NUMBER; pstring tokstr = ""; while (true) { - if (m_identifier_chars.find(c)>=0 && m_number_chars.find(c)<0) + if (m_identifier_chars.find(c) != m_identifier_chars.end() && m_number_chars.find(c) == m_number_chars.end()) ret = IDENTIFIER; - else if (m_number_chars.find(c)<0) + else if (m_number_chars.find(c) == m_number_chars.end()) break; tokstr += c; c = getc(); } - ungetc(); + ungetc(c); return token_t(ret, tokstr); } - else if (m_identifier_chars.find(c)>=0) + else if (m_identifier_chars.find(c) != m_identifier_chars.end()) { /* read identifier till non identifier char */ pstring tokstr = ""; - while (m_identifier_chars.find(c)>=0) { + while (m_identifier_chars.find(c) != m_identifier_chars.end()) { tokstr += c; c = getc(); } - ungetc(); - token_id_t id(plib::container::indexof(m_tokens, tokstr)); - if (id.id() >= 0) - return token_t(id, tokstr); + ungetc(c); + auto id = m_tokens.find(tokstr); + if (id != m_tokens.end()) + return token_t(id->second, tokstr); else - { return token_t(IDENTIFIER, tokstr); - } } else if (c == m_string) { @@ -222,27 +228,24 @@ ptokenizer::token_t ptokenizer::get_token_internal() { /* read identifier till first identifier char or ws */ pstring tokstr = ""; - while ((m_identifier_chars.find(c)) < 0 && (m_whitespace.find(c) < 0)) { + while ((m_identifier_chars.find(c)) == m_identifier_chars.end() && (m_whitespace.find(c) == m_whitespace.end())) { tokstr += c; /* expensive, check for single char tokens */ if (tokstr.len() == 1) { - token_id_t id(plib::container::indexof(m_tokens, tokstr)); - if (id.id() >= 0) - return token_t(id, tokstr); + auto id = m_tokens.find(tokstr); + if (id != m_tokens.end()) + return token_t(id->second, tokstr); } c = getc(); } - ungetc(); - token_id_t id(plib::container::indexof(m_tokens, tokstr)); - if (id.id() >= 0) - return token_t(id, tokstr); + ungetc(c); + auto id = m_tokens.find(tokstr); + if (id != m_tokens.end()) + return token_t(id->second, tokstr); else - { return token_t(UNKNOWN, tokstr); - } } - } void ptokenizer::error(const pstring &errs) @@ -406,7 +409,7 @@ pstring ppreprocessor::process_line(const pstring &line) std::size_t start = 0; lt = replace_macros(lt); pstring_vector_t t(lt.substr(3).replace(" ",""), m_expr_sep); - int val = expr(t, start, 0); + int val = static_cast<int>(expr(t, start, 0)); if (val == 0) m_ifflag |= (1 << m_level); } diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index 463fdad9b76..301a4fc30a2 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -25,7 +25,7 @@ public: virtual ~ptokenizer() {} explicit ptokenizer(pistream &strm) - : m_strm(strm), m_lineno(0), m_px(0), m_string('"') + : m_strm(strm), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"') {} enum token_type @@ -42,32 +42,29 @@ public: struct token_id_t { public: - token_id_t() : m_id(-2) {} - token_id_t(const int id) : m_id(id) {} - int id() const { return m_id; } + + static const std::size_t npos = static_cast<std::size_t>(-1); + + token_id_t() : m_id(npos) {} + token_id_t(const std::size_t id) : m_id(id) {} + std::size_t id() const { return m_id; } private: - int m_id; + std::size_t m_id; }; struct token_t { token_t(token_type type) + : m_type(type), m_id(), m_token("") { - m_type = type; - m_id = token_id_t(-1); - m_token =""; } token_t(token_type type, const pstring &str) + : m_type(type), m_id(), m_token(str) { - m_type = type; - m_id = token_id_t(-1); - m_token = str; } token_t(const token_id_t id, const pstring &str) + : m_type(TOKEN), m_id(id), m_token(str) { - m_type = TOKEN; - m_id = id; - m_token = str; } bool is(const token_id_t &tok_id) const { return m_id.id() == tok_id.id(); } @@ -101,13 +98,14 @@ public: token_id_t register_token(pstring token) { - m_tokens.push_back(token); - return token_id_t(m_tokens.size() - 1); + token_id_t ret(m_tokens.size()); + m_tokens.emplace(token, ret); + return ret; } void set_identifier_chars(pstring s) { m_identifier_chars = s; } void set_number_chars(pstring st, pstring rem) { m_number_chars_start = st; m_number_chars = rem; } - void set_string_char(char c) { m_string = c; } + void set_string_char(pstring::code_t c) { m_string = c; } void set_whitespace(pstring s) { m_whitespace = s; } void set_comment(pstring start, pstring end, pstring line) { @@ -126,7 +124,7 @@ private: void skipeol(); pstring::code_t getc(); - void ungetc(); + void ungetc(pstring::code_t c); bool eof() { return m_strm.eof(); } @@ -134,14 +132,15 @@ private: int m_lineno; pstring m_cur_line; - unsigned m_px; + pstring::iterator m_px; + pstring::code_t m_unget; /* tokenizer stuff follows ... */ pstring m_identifier_chars; pstring m_number_chars; pstring m_number_chars_start; - std::vector<pstring> m_tokens; + std::unordered_map<pstring, token_id_t> m_tokens; pstring m_whitespace; pstring::code_t m_string; diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp index 753671ceeda..61535acac09 100644 --- a/src/lib/netlist/plib/pstate.cpp +++ b/src/lib/netlist/plib/pstate.cpp @@ -19,7 +19,7 @@ state_manager_t::~state_manager_t() -void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const int count, void *ptr) +void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const std::size_t count, void *ptr) { auto p = plib::make_unique<entry_t>(stname, dt, owner, count, ptr); m_save.push_back(std::move(p)); diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index df6dd4d7901..cd6c8efe38b 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -113,7 +113,7 @@ public: save_state_ptr(owner, stname, datatype_f<C>::f(), N, &(state[0])); } - template<typename C> void save_item(const void *owner, C *state, const pstring &stname, const int count) + template<typename C> void save_item(const void *owner, C *state, const pstring &stname, const std::size_t count) { save_state_ptr(owner, stname, datatype_f<C>::f(), count, state); } @@ -130,7 +130,7 @@ public: const entry_t::list_t &save_list() const { return m_save; } - void save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const int count, void *ptr); + void save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const std::size_t count, void *ptr); protected: diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp index 9fcede380d5..ad2010213f9 100644 --- a/src/lib/netlist/plib/pstream.cpp +++ b/src/lib/netlist/plib/pstream.cpp @@ -47,7 +47,7 @@ bool pistream::readline(pstring &line) void postream::write(pistream &strm) { char buf[1024]; - unsigned r; + pos_type r; while ((r=strm.read(buf, 1024)) > 0) write(buf, r); } @@ -78,9 +78,9 @@ pifilestream::pifilestream(void *file, const pstring name, const bool do_close) void pifilestream::init() { - if (ftell((FILE *) m_file) >= 0) + if (ftell(static_cast<FILE *>(m_file)) >= 0) { - if (fseek((FILE *) m_file, 0, SEEK_SET) >= 0) + if (fseek(static_cast<FILE *>(m_file), 0, SEEK_SET) >= 0) set_flag(FLAG_SEEKABLE); } } @@ -89,18 +89,18 @@ pifilestream::~pifilestream() { if (m_actually_close) { - fclose((FILE *) m_file); + fclose(static_cast<FILE *>(m_file)); } } -unsigned pifilestream::vread(void *buf, const unsigned n) +pifilestream::pos_type pifilestream::vread(void *buf, const pos_type n) { - std::size_t r = fread(buf, 1, n, (FILE *) m_file); + pos_type r = fread(buf, 1, n, static_cast<FILE *>(m_file)); if (r < n) { - if (feof((FILE *) m_file)) + if (feof(static_cast<FILE *>(m_file))) set_flag(FLAG_EOF); - if (ferror((FILE *) m_file)) + if (ferror(static_cast<FILE *>(m_file))) throw file_read_e(m_filename); } m_pos += r; @@ -109,27 +109,27 @@ unsigned pifilestream::vread(void *buf, const unsigned n) void pifilestream::vseek(const pos_type n) { - if (fseek((FILE *) m_file, SEEK_SET, n) < 0) + if (fseek(static_cast<FILE *>(m_file), static_cast<long>(n), SEEK_SET) < 0) throw file_e("File seek failed: {}", m_filename); else m_pos = n; - if (feof((FILE *) m_file)) + if (feof(static_cast<FILE *>(m_file))) set_flag(FLAG_EOF); else clear_flag(FLAG_EOF); - if (ferror((FILE *) m_file)) + if (ferror(static_cast<FILE *>(m_file))) throw file_e("Generic file operation failed: {}", m_filename); } pifilestream::pos_type pifilestream::vtell() { - long ret = ftell((FILE *) m_file); + long ret = ftell(static_cast<FILE *>(m_file)); if (ret < 0) { return m_pos; } else - return ret; + return static_cast<pos_type>(ret); } // ----------------------------------------------------------------------------- @@ -164,23 +164,23 @@ pofilestream::pofilestream(void *file, const pstring name, const bool do_close) void pofilestream::init() { - if (ftell((FILE *) m_file) >= 0) - if (fseek((FILE *) m_file, 0, SEEK_SET) >= 0) + if (ftell(static_cast<FILE *>(m_file)) >= 0) + if (fseek(static_cast<FILE *>(m_file), 0, SEEK_SET) >= 0) set_flag(FLAG_SEEKABLE); } pofilestream::~pofilestream() { if (m_actually_close) - fclose((FILE *) m_file); + fclose(static_cast<FILE *>(m_file)); } -void pofilestream::vwrite(const void *buf, const unsigned n) +void pofilestream::vwrite(const void *buf, const pos_type n) { - std::size_t r = fwrite(buf, 1, n, (FILE *) m_file); + std::size_t r = fwrite(buf, 1, n, static_cast<FILE *>(m_file)); if (r < n) { - if (ferror((FILE *) m_file)) + if (ferror(static_cast<FILE *>(m_file))) throw file_write_e(m_filename); } m_pos += r; @@ -188,25 +188,25 @@ void pofilestream::vwrite(const void *buf, const unsigned n) void pofilestream::vseek(const pos_type n) { - if (fseek((FILE *) m_file, SEEK_SET, n) < 0) + if (fseek(static_cast<FILE *>(m_file), static_cast<long>(n), SEEK_SET) < 0) throw file_e("File seek failed: {}", m_filename); else { m_pos = n; - if (ferror((FILE *) m_file)) + if (ferror(static_cast<FILE *>(m_file))) throw file_e("Generic file operation failed: {}", m_filename); } } pstream::pos_type pofilestream::vtell() { - long ret = ftell((FILE *) m_file); + std::ptrdiff_t ret = ftell(static_cast<FILE *>(m_file)); if (ret < 0) { return m_pos; } else - return ret; + return static_cast<pos_type>(ret); } // ----------------------------------------------------------------------------- @@ -232,12 +232,12 @@ pstdout::pstdout() // ----------------------------------------------------------------------------- pimemstream::pimemstream(const void *mem, const pos_type len) - : pistream(FLAG_SEEKABLE), m_pos(0), m_len(len), m_mem((char *) mem) + : pistream(FLAG_SEEKABLE), m_pos(0), m_len(len), m_mem(static_cast<const pstring::mem_t *>(mem)) { } pimemstream::pimemstream(const pomemstream &ostrm) -: pistream(FLAG_SEEKABLE), m_pos(0), m_len(ostrm.size()), m_mem((char *) ostrm.memory()) +: pistream(FLAG_SEEKABLE), m_pos(0), m_len(ostrm.size()), m_mem(reinterpret_cast<pstring::mem_t *>(ostrm.memory())) { } @@ -245,9 +245,9 @@ pimemstream::~pimemstream() { } -unsigned pimemstream::vread(void *buf, const unsigned n) +pimemstream::pos_type pimemstream::vread(void *buf, const pos_type n) { - unsigned ret = (m_pos + n <= m_len) ? n : m_len - m_pos; + pos_type ret = (m_pos + n <= m_len) ? n : m_len - m_pos; if (ret > 0) { @@ -288,7 +288,7 @@ pomemstream::~pomemstream() pfree_array(m_mem); } -void pomemstream::vwrite(const void *buf, const unsigned n) +void pomemstream::vwrite(const void *buf, const pos_type n) { if (m_pos + n >= m_capacity) { diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index 1e9a3ed6a1c..68ab55ca58b 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -27,7 +27,7 @@ public: using pos_type = std::size_t; - static constexpr pos_type SEEK_EOF = (pos_type) -1; + static constexpr pos_type SEEK_EOF = static_cast<pos_type>(-1); explicit pstream(const unsigned flags) : m_flags(flags) { @@ -92,14 +92,14 @@ public: return (read(&b, 1) == 1); } - unsigned read(void *buf, const unsigned n) + pos_type read(void *buf, const unsigned n) { return vread(buf, n); } protected: /* read up to n bytes from stream */ - virtual unsigned vread(void *buf, const unsigned n) = 0; + virtual pos_type vread(void *buf, const pos_type n) = 0; private: pstringbuffer m_linebuf; @@ -135,7 +135,7 @@ public: write(&c, 1); } - void write(const void *buf, const unsigned n) + void write(const void *buf, const pos_type n) { vwrite(buf, n); } @@ -144,7 +144,7 @@ public: protected: /* write n bytes to stream */ - virtual void vwrite(const void *buf, const unsigned n) = 0; + virtual void vwrite(const void *buf, const pos_type n) = 0; private: }; @@ -162,11 +162,11 @@ public: virtual ~pomemstream(); char *memory() const { return m_mem; } - unsigned size() const { return m_size; } + pos_type size() const { return m_size; } protected: /* write n bytes to stream */ - virtual void vwrite(const void *buf, const unsigned n) override; + virtual void vwrite(const void *buf, const pos_type) override; virtual void vseek(const pos_type n) override; virtual pos_type vtell() override; @@ -190,7 +190,7 @@ public: protected: /* write n bytes to stream */ - virtual void vwrite(const void *buf, const unsigned n) override + virtual void vwrite(const void *buf, const pos_type n) override { m_buf.cat(buf, n); } @@ -216,7 +216,7 @@ public: protected: pofilestream(void *file, const pstring name, const bool do_close); /* write n bytes to stream */ - virtual void vwrite(const void *buf, const unsigned n) override; + virtual void vwrite(const void *buf, const pos_type n) override; virtual void vseek(const pos_type n) override; virtual pos_type vtell() override; @@ -267,7 +267,7 @@ protected: pifilestream(void *file, const pstring name, const bool do_close); /* read up to n bytes from stream */ - virtual unsigned vread(void *buf, const unsigned n) override; + virtual pos_type vread(void *buf, const pos_type n) override; virtual void vseek(const pos_type n) override; virtual pos_type vtell() override; @@ -307,14 +307,14 @@ public: protected: /* read up to n bytes from stream */ - virtual unsigned vread(void *buf, const unsigned n) override; + virtual pos_type vread(void *buf, const pos_type n) override; virtual void vseek(const pos_type n) override; virtual pos_type vtell() override; private: pos_type m_pos; pos_type m_len; - char *m_mem; + const char *m_mem; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp index 4db3de10503..644f7d6f49a 100644 --- a/src/lib/netlist/plib/pstring.cpp +++ b/src/lib/netlist/plib/pstring.cpp @@ -32,7 +32,7 @@ pstring_t<F>::~pstring_t() template<typename F> void pstring_t<F>::pcat(const mem_t *s) { - int slen = strlen(s); + std::size_t slen = strlen(s); pstr_t *n = salloc(m_ptr->len() + slen); if (m_ptr->len() > 0) std::memcpy(n->str(), m_ptr->str(), m_ptr->len()); @@ -46,7 +46,7 @@ void pstring_t<F>::pcat(const mem_t *s) template<typename F> void pstring_t<F>::pcat(const pstring_t &s) { - int slen = s.blen(); + std::size_t slen = s.blen(); pstr_t *n = salloc(m_ptr->len() + slen); if (m_ptr->len() > 0) std::memcpy(n->str(), m_ptr->str(), m_ptr->len()); @@ -60,7 +60,7 @@ void pstring_t<F>::pcat(const pstring_t &s) template<typename F> int pstring_t<F>::pcmp(const pstring_t &right) const { - long l = std::min(blen(), right.blen()); + std::size_t l = std::min(blen(), right.blen()); if (l == 0) { if (blen() == 0 && right.blen() == 0) @@ -72,18 +72,18 @@ int pstring_t<F>::pcmp(const pstring_t &right) const } int ret = memcmp(m_ptr->str(), right.cstr(), l); if (ret == 0) - ret = this->blen() - right.blen(); - if (ret < 0) - return -1; - else if (ret > 0) - return 1; - else - return 0; + { + if (this->blen() > right.blen()) + ret = 1; + else if (this->blen() < right.blen()) + ret = -1; + } + return ret; } template<typename F> -void pstring_t<F>::pcopy(const mem_t *from, int size) +void pstring_t<F>::pcopy(const mem_t *from, std::size_t size) { pstr_t *n = salloc(size); if (size > 0) @@ -94,139 +94,128 @@ void pstring_t<F>::pcopy(const mem_t *from, int size) } template<typename F> -const pstring_t<F> pstring_t<F>::substr(unsigned start, unsigned count) const +const pstring_t<F> pstring_t<F>::substr(const iterator start, const iterator end) const { pstring_t ret; - unsigned alen = len(); - if (start >= alen || count == 0) - return ret; - if (start + count > alen) - count = alen - start; - const mem_t *p = cstr(); - // find start - for (unsigned i=0; i<start; i++) - p += F::codelen(p); - const char *e = p; - for (unsigned i=0; i<count; i++) - e += F::codelen(e); - ret.pcopy(p, e-p); + //FIXME: throw ? + ret.pcopy(start.p, static_cast<std::size_t>(end.p - start.p)); return ret; } + template<typename F> const pstring_t<F> pstring_t<F>::ucase() const { pstring_t ret = *this; ret.pcopy(cstr(), blen()); for (std::size_t i=0; i<ret.len(); i++) - ret.m_ptr->str()[i] = toupper((unsigned) ret.m_ptr->str()[i]); + ret.m_ptr->str()[i] = static_cast<char>(toupper(static_cast<int>(ret.m_ptr->str()[i]))); return ret; } template<typename F> -int pstring_t<F>::find_first_not_of(const pstring_t &no) const +typename pstring_t<F>::iterator pstring_t<F>::find_first_not_of(const pstring_t &no) const { - char *t = m_ptr->str(); - unsigned nolen = no.len(); - unsigned tlen = len(); - for (std::size_t i=0; i < tlen; i++) + for (auto it = begin(); it != end(); ++it) { - char *n = no.m_ptr->str(); bool f = true; - for (std::size_t j=0; j < nolen; j++) + for (auto const jt : no) { - if (F::code(t) == F::code(n)) + if (*it == jt) + { f = false; - n += F::codelen(t); + break; + } } if (f) - return i; - t += F::codelen(t); + return it; } - return -1; + return end(); } template<typename F> -int pstring_t<F>::find_last_not_of(const pstring_t &no) const +typename pstring_t<F>::iterator pstring_t<F>::find_last_not_of(const pstring_t &no) const { - char *t = m_ptr->str(); - unsigned nolen = no.len(); - unsigned tlen = len(); - int last_found = -1; - for (std::size_t i=0; i < tlen; i++) + /* FIXME: reverse iterator */ + iterator last_found = end(); + for (auto it = begin(); it != end(); ++it) { - char *n = no.m_ptr->str(); bool f = true; - for (std::size_t j=0; j < nolen; j++) + for (auto const jt : no) { - if (F::code(t) == F::code(n)) + if (*it == jt) + { f = false; - n += F::codelen(t); + break; + } } if (f) - last_found = i; - t += F::codelen(t); + last_found = it; } return last_found; } template<typename F> -pstring_t<F> pstring_t<F>::replace(const pstring_t &search, const pstring_t &replace) const +typename pstring_t<F>::iterator pstring_t<F>::find(const pstring_t &search, iterator start) const { - // FIXME: use this pstringbuffer ret = ""; - pstring_t ret = ""; - const int slen = search.blen(); - const int tlen = blen(); - - if (slen == 0 || tlen < slen ) - return *this; - int i = 0; - while (i < tlen - slen + 1) + for (; start != end(); ++start) { - if (memcmp(cstr()+i,search.cstr(),slen) == 0) - { - ret += replace; - i += slen; - } - else + iterator itc(start); + auto cmp = search.begin(); + while (itc != end() && cmp != search.end() && *itc == *cmp) { - /* avoid adding a code, cat a string ... */ - mem_t buf[2] = { *(cstr() + i), 0 }; - ret = ret.cat(buf); - i++; + ++itc; + ++cmp; } + if (cmp == search.end()) + return start; + } + return end(); +} + +template<typename F> +pstring_t<F> pstring_t<F>::replace(const pstring_t &search, const pstring_t &replace) const +{ + pstring_t ret(""); + const size_type slen = search.len(); + + auto last_s = begin(); + auto s = find(search, last_s); + while (s != end()) + { + ret += substr(last_s, s); + ret += replace; + last_s = s + slen; + s = find(search, last_s); } - ret = ret.cat(cstr() + i); + ret += substr(last_s, end()); return ret; } template<typename F> const pstring_t<F> pstring_t<F>::ltrim(const pstring_t &ws) const { - int f = find_first_not_of(ws); - if (f>=0) - return substr(f); - else - return ""; + return substr(find_first_not_of(ws), end()); } template<typename F> const pstring_t<F> pstring_t<F>::rtrim(const pstring_t &ws) const { - int f = find_last_not_of(ws); - if (f>=0) - return left(f+1); + auto f = find_last_not_of(ws); + if (f==end()) + return pstring_t(""); else - return ""; + return substr(begin(), f + 1); } template<typename F> -const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const unsigned cnt) const +const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const size_type cnt) const { // FIXME: pstringbuffer ret(*this); pstring_t ret(*this); - while (ret.len() < cnt) + size_type wsl = ws.len(); + for (auto i = ret.len(); i < cnt; i+=wsl) ret += ws; return ret; } @@ -271,6 +260,133 @@ long pstring_t<F>::as_long(bool *error) const return ret; } +template<typename F> +typename pstring_t<F>::iterator pstring_t<F>::find(const mem_t *search, iterator start) const +{ + for (; start != end(); ++start) + { + iterator itc(start); + iterator cmp(search); + while (itc != end() && *cmp != 0 && *itc == *cmp) + { + ++itc; + ++cmp; + } + if (*cmp == 0) + return start; + } + return end(); +} + +template<typename F> +bool pstring_t<F>::startsWith(const pstring_t &arg) const +{ + if (arg.blen() > blen()) + return false; + else + return (memcmp(arg.cstr(), cstr(), arg.blen()) == 0); +} + +template<typename F> +bool pstring_t<F>::endsWith(const pstring_t &arg) const +{ + if (arg.blen() > blen()) + return false; + else + return (memcmp(cstr()+this->blen()-arg.blen(), arg.cstr(), arg.blen()) == 0); +} + + +template<typename F> +bool pstring_t<F>::startsWith(const mem_t *arg) const +{ + std::size_t alen = strlen(arg); + if (alen > blen()) + return false; + else + return (memcmp(arg, cstr(), alen) == 0); +} + +template<typename F> +int pstring_t<F>::pcmp(const mem_t *right) const +{ + return std::strcmp(m_ptr->str(), right); +} + +// ---------------------------------------------------------------------------------------- +// pstringbuffer +// ---------------------------------------------------------------------------------------- + +pstringbuffer::~pstringbuffer() +{ + if (m_ptr != nullptr) + plib::pfree_array(m_ptr); +} + +void pstringbuffer::resize(const std::size_t size) +{ + if (m_ptr == nullptr) + { + m_size = DEFAULT_SIZE; + while (m_size <= size) + m_size *= 2; + m_ptr = plib::palloc_array<char>(m_size); + *m_ptr = 0; + m_len = 0; + } + else if (m_size < size) + { + while (m_size < size) + m_size *= 2; + char *new_buf = plib::palloc_array<char>(m_size); + std::memcpy(new_buf, m_ptr, m_len + 1); + plib::pfree_array(m_ptr); + m_ptr = new_buf; + } +} + +void pstringbuffer::pcopy(const char *from) +{ + std::size_t nl = strlen(from) + 1; + resize(nl); + std::memcpy(m_ptr, from, nl); +} + +void pstringbuffer::pcopy(const pstring &from) +{ + std::size_t nl = from.blen() + 1; + resize(nl); + std::memcpy(m_ptr, from.cstr(), nl); +} + +void pstringbuffer::pcat(const char *s) +{ + const std::size_t slen = std::strlen(s); + const std::size_t nl = m_len + slen + 1; + resize(nl); + std::memcpy(m_ptr + m_len, s, slen + 1); + m_len += slen; +} + +void pstringbuffer::pcat(const void *m, std::size_t l) +{ + const std::size_t nl = m_len + l + 1; + resize(nl); + std::memcpy(m_ptr + m_len, m, l); + m_len += l; + *(m_ptr + m_len) = 0; +} + +void pstringbuffer::pcat(const pstring &s) +{ + const std::size_t slen = s.blen(); + const std::size_t nl = m_len + slen + 1; + resize(nl); + std::memcpy(m_ptr + m_len, s.cstr(), slen); + m_len += slen; + m_ptr[m_len] = 0; +} + // ---------------------------------------------------------------------------------------- // static stuff ... // ---------------------------------------------------------------------------------------- @@ -285,11 +401,11 @@ long pstring_t<F>::as_long(bool *error) const static std::stack<pstr_t *> *stk = nullptr; -static inline unsigned countleadbits(unsigned x) +static inline std::size_t countleadbits(std::size_t x) { #ifndef count_leading_zeros - unsigned msk; - unsigned ret; + std::size_t msk; + std::size_t ret; if (x < 0x100) { msk = 0x80; @@ -329,25 +445,25 @@ void pstring_t<F>::sfree(pstr_t *s) { if (stk != nullptr) { - unsigned sn= ((32 - countleadbits(s->len())) + 1) / 2; + size_type sn= ((32 - countleadbits(s->len())) + 1) / 2; stk[sn].push(s); } else - plib::pfree_array(((char *)s)); + plib::pfree_array(reinterpret_cast<char *>(s)); //_mm_free(((char *)s)); } } template<typename F> -pstr_t *pstring_t<F>::salloc(int n) +pstr_t *pstring_t<F>::salloc(std::size_t n) { if (stk == nullptr) stk = plib::palloc_array<std::stack<pstr_t *>>(17); pstr_t *p; std::size_t sn= ((32 - countleadbits(n)) + 1) / 2; - std::size_t size = sizeof(pstr_t) + ((std::size_t) 1<<(sn * 2)) + 1; + std::size_t size = sizeof(pstr_t) + (static_cast<std::size_t>(1)<<(sn * 2)) + 1; if (stk[sn].empty()) - p = (pstr_t *) plib::palloc_array<char>(size); + p = reinterpret_cast<pstr_t *>(plib::palloc_array<char>(size)); else { p = stk[sn].top(); @@ -384,7 +500,7 @@ void pstring_t<F>::sfree(pstr_t *s) s->m_ref_count--; if (s->m_ref_count == 0 && s != &m_zero) { - pfree_array(((char *)s)); + plib::pfree_array(((char *)s)); //_mm_free(((char *)s)); } } @@ -393,7 +509,7 @@ template<typename F> pstr_t *pstring_t<F>::salloc(int n) { int size = sizeof(pstr_t) + n + 1; - pstr_t *p = (pstr_t *) palloc_array(char, size); + pstr_t *p = (pstr_t *) plib::palloc_array<char>(size); // str_t *p = (str_t *) mm_malloc(size, 8); p->init(n); return p; @@ -406,168 +522,9 @@ void pstring_t<F>::resetmem() } #endif - -// ---------------------------------------------------------------------------------------- -// pstring ... -// ---------------------------------------------------------------------------------------- - -template<typename F> -int pstring_t<F>::find(const pstring_t &search, unsigned start) const -{ - const unsigned tlen = len(); - const unsigned slen = search.len(); - const mem_t *s = search.cstr(); - const unsigned startt = std::min(start, tlen); - const mem_t *t = cstr(); - for (std::size_t i=0; i<startt; i++) - t += F::codelen(t); - for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) - { - if (F::code(t) == F::code(s)) - if (std::memcmp(t,s,search.blen())==0) - return i+startt; - t += F::codelen(t); - } - return -1; -} - -template<typename F> -int pstring_t<F>::find(const mem_t *search, unsigned start) const -{ - const unsigned tlen = len(); - unsigned slen = 0; - unsigned sblen = 0; - const mem_t *x = search; - while (*x != 0) - { - slen++; - const unsigned sl = F::codelen(x); - x += sl; - sblen += sl; - } - const char *s = search; - const unsigned startt = std::min(start, tlen); - const char *t = cstr(); - for (std::size_t i=0; i<startt; i++) - t += F::codelen(t); - for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) - { - if (F::code(t) == F::code(s)) - if (std::memcmp(t,s,sblen)==0) - return i+startt; - t += F::codelen(t); - } - return -1; -} - -template<typename F> -bool pstring_t<F>::startsWith(const pstring_t &arg) const -{ - if (arg.blen() > blen()) - return false; - else - return (memcmp(arg.cstr(), cstr(), arg.len()) == 0); -} - -template<typename F> -bool pstring_t<F>::endsWith(const pstring_t &arg) const -{ - if (arg.blen() > blen()) - return false; - else - return (memcmp(cstr()+this->len()-arg.len(), arg.cstr(), arg.len()) == 0); -} - - -template<typename F> -bool pstring_t<F>::startsWith(const mem_t *arg) const -{ - unsigned alen = strlen(arg); - if (alen > blen()) - return false; - else - return (memcmp(arg, cstr(), alen) == 0); -} - -template<typename F> -int pstring_t<F>::pcmp(const mem_t *right) const -{ - return std::strcmp(m_ptr->str(), right); -} - // ---------------------------------------------------------------------------------------- -// pstringbuffer +// template stuff ... // ---------------------------------------------------------------------------------------- -pstringbuffer::~pstringbuffer() -{ - if (m_ptr != nullptr) - plib::pfree_array(m_ptr); -} - -void pstringbuffer::resize(const std::size_t size) -{ - if (m_ptr == nullptr) - { - m_size = DEFAULT_SIZE; - while (m_size <= size) - m_size *= 2; - m_ptr = plib::palloc_array<char>(m_size); - *m_ptr = 0; - m_len = 0; - } - else if (m_size < size) - { - while (m_size < size) - m_size *= 2; - char *new_buf = plib::palloc_array<char>(m_size); - std::memcpy(new_buf, m_ptr, m_len + 1); - plib::pfree_array(m_ptr); - m_ptr = new_buf; - } -} - -void pstringbuffer::pcopy(const char *from) -{ - std::size_t nl = strlen(from) + 1; - resize(nl); - std::memcpy(m_ptr, from, nl); -} - -void pstringbuffer::pcopy(const pstring &from) -{ - std::size_t nl = from.blen() + 1; - resize(nl); - std::memcpy(m_ptr, from.cstr(), nl); -} - -void pstringbuffer::pcat(const char *s) -{ - const std::size_t slen = std::strlen(s); - const std::size_t nl = m_len + slen + 1; - resize(nl); - std::memcpy(m_ptr + m_len, s, slen + 1); - m_len += slen; -} - -void pstringbuffer::pcat(const void *m, unsigned l) -{ - const std::size_t nl = m_len + l + 1; - resize(nl); - std::memcpy(m_ptr + m_len, m, l); - m_len += l; - *(m_ptr + m_len) = 0; -} - -void pstringbuffer::pcat(const pstring &s) -{ - const std::size_t slen = s.blen(); - const std::size_t nl = m_len + slen + 1; - resize(nl); - std::memcpy(m_ptr + m_len, s.cstr(), slen); - m_len += slen; - m_ptr[m_len] = 0; -} - template struct pstring_t<pu8_traits>; template struct pstring_t<putf8_traits>; diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index df4d79d587f..e7c8b3ba0dc 100644 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -9,6 +9,7 @@ #include <cstdarg> #include <cstddef> +#include <iterator> #include "pconfig.h" @@ -22,21 +23,22 @@ struct pstr_t { //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; } - pstr_t(const unsigned alen) + pstr_t(const std::size_t alen) { init(alen); } - void init(const unsigned alen) + void init(const std::size_t alen) { m_ref_count = 1; m_len = alen; m_str[0] = 0; } char *str() { return &m_str[0]; } - unsigned len() const { return m_len; } + unsigned char *ustr() { return reinterpret_cast<unsigned char *>(&m_str[0]); } + std::size_t len() const { return m_len; } int m_ref_count; private: - unsigned m_len; + std::size_t m_len; char m_str[1]; }; @@ -47,8 +49,9 @@ struct pstring_t public: typedef F traits; - typedef typename traits::mem_t mem_t; - typedef typename traits::code_t code_t; + typedef typename F::mem_t mem_t; + typedef typename F::code_t code_t; + typedef std::size_t size_type; // simple construction/destruction pstring_t() @@ -66,6 +69,26 @@ public: pstring_t &operator=(const mem_t *string) { pcopy(string); return *this; } pstring_t &operator=(const pstring_t &string) { pcopy(string); return *this; } + struct iterator final : public std::iterator<std::forward_iterator_tag, mem_t> + { + const mem_t * p; + public: + explicit constexpr iterator(const mem_t *x) noexcept : p(x) {} + iterator(const iterator &rhs) noexcept = default; + iterator(iterator &&rhs) noexcept { p = rhs.p; } + iterator &operator=(const iterator &it) { p = it.p; return *this; } + iterator& operator++() noexcept {p += traits::codelen(p); return *this;} + iterator operator++(int) noexcept {iterator tmp(*this); operator++(); return tmp;} + bool operator==(const iterator& rhs) noexcept {return p==rhs.p;} + bool operator!=(const iterator& rhs) noexcept {return p!=rhs.p;} + const code_t operator*() noexcept {return traits::code(p);} + iterator& operator+=(size_type count) { while (count>0) { --count; ++(*this); } return *this; } + friend iterator operator+(iterator lhs, const size_type &rhs) { return (lhs += rhs); } + }; + + iterator begin() const { return iterator(m_ptr->str()); } + iterator end() const { return iterator(m_ptr->str() + blen()); } + // C string conversion helpers const mem_t *cstr() const { return m_ptr->str(); } @@ -93,8 +116,8 @@ public: bool equals(const pstring_t &string) const { return (pcmp(string) == 0); } - int cmp(const pstring_t &string) const { return pcmp(string); } - int cmp(const mem_t *string) const { return pcmp(string); } + //int cmp(const pstring_t &string) const { return pcmp(string); } + //int cmp(const mem_t *string) const { return pcmp(string); } bool startsWith(const pstring_t &arg) const; bool startsWith(const mem_t *arg) const; @@ -107,47 +130,45 @@ public: const pstring_t cat(const pstring_t &s) const { return *this + s; } const pstring_t cat(const mem_t *s) const { return *this + s; } - unsigned blen() const { return m_ptr->len(); } + size_type blen() const { return m_ptr->len(); } // conversions double as_double(bool *error = nullptr) const; long as_long(bool *error = nullptr) const; - unsigned len() const + size_type len() const { return traits::len(m_ptr); } - pstring_t& operator+=(const code_t c) { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(c, buf); pcat(buf); return *this; } + pstring_t& operator+=(const code_t c) { mem_t buf[traits::MAXCODELEN+1] = { 0 }; traits::encode(c, buf); pcat(buf); return *this; } friend pstring_t operator+(const pstring_t &lhs, const code_t rhs) { return pstring_t(lhs) += rhs; } - int find(const pstring_t &search, unsigned start = 0) const; - int find(const mem_t *search, unsigned start = 0) const; - int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); } + iterator find(const pstring_t &search, iterator start) const; + iterator find(const pstring_t &search) const { return find(search, begin()); } + iterator find(const mem_t *search, iterator start) const; + iterator find(const mem_t *search) const { return find(search, begin()); } + iterator find(const code_t search, iterator start) const { mem_t buf[traits::MAXCODELEN+1] = { 0 }; traits::encode(search, buf); return find(buf, start); } + iterator find(const code_t search) const { return find(search, begin()); } - const pstring_t substr(unsigned start, unsigned count) const ; - const pstring_t substr(unsigned start) const { if (start>=len()) return pstring_t(""); else return substr(start, len()-start); } + const pstring_t substr(const iterator start, const iterator end) const ; + const pstring_t substr(const iterator start) const { return substr(start, end()); } + const pstring_t substr(size_type start) const { if (start>=len()) return pstring_t(""); else return substr(begin() + start, end()); } - const pstring_t left(unsigned count) const { return substr(0, count); } - const pstring_t right(unsigned count) const { if (len()<count) return pstring_t(*this); else return substr(len() - count, count); } + const pstring_t left(iterator leftof) const { return substr(begin(), leftof); } + const pstring_t right(iterator pos) const { return substr(pos, end()); } - int find_first_not_of(const pstring_t &no) const; - int find_last_not_of(const pstring_t &no) const; + iterator find_first_not_of(const pstring_t &no) const; + iterator find_last_not_of(const pstring_t &no) const; const pstring_t ltrim(const pstring_t &ws = " \t\n\r") const; const pstring_t rtrim(const pstring_t &ws = " \t\n\r") const; const pstring_t trim(const pstring_t &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); } - const pstring_t rpad(const pstring_t &ws, const unsigned cnt) const; - - /* - * everything below MAY not work for utf8. - * Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8 - */ + const pstring_t rpad(const pstring_t &ws, const size_type cnt) const; - // FIXME: - code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); } + code_t code_at(const size_type pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); } const pstring_t ucase() const; @@ -168,7 +189,7 @@ private: int pcmp(const mem_t *right) const; - void pcopy(const mem_t *from, int size); + void pcopy(const mem_t *from, std::size_t size); void pcopy(const mem_t *from); @@ -182,7 +203,7 @@ private: void pcat(const mem_t *s); void pcat(const pstring_t &s); - static pstr_t *salloc(int n); + static pstr_t *salloc(std::size_t n); static void sfree(pstr_t *s); static pstr_t m_zero; @@ -193,12 +214,12 @@ struct pu8_traits static const unsigned MAXCODELEN = 1; /* in memory units */ typedef char mem_t; typedef char code_t; - static unsigned len(const pstr_t *p) { return p->len(); } + static std::size_t len(const pstr_t *p) { return p->len(); } static unsigned codelen(const mem_t *p) { return 1; } static unsigned codelen(const code_t c) { return 1; } static code_t code(const mem_t *p) { return *p; } static void encode(const code_t c, mem_t *p) { *p = c; } - static const mem_t *nthcode(const mem_t *p, const unsigned n) { return &(p[n]); } + static const mem_t *nthcode(const mem_t *p, const std::size_t n) { return &(p[n]); } }; /* No checking, this may deliver invalid codes */ @@ -207,10 +228,10 @@ struct putf8_traits static const unsigned MAXCODELEN = 4; /* in memory units, RFC 3629 */ typedef char mem_t; typedef unsigned code_t; - static unsigned len(pstr_t *p) + static std::size_t len(pstr_t *p) { - unsigned ret = 0; - unsigned char *c = (unsigned char *) p->str(); + std::size_t ret = 0; + unsigned char *c = p->ustr(); while (*c) { if (!((*c & 0xC0) == 0x80)) @@ -221,7 +242,7 @@ struct putf8_traits } static unsigned codelen(const mem_t *p) { - unsigned char *p1 = (unsigned char *) p; + const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p); if ((*p1 & 0x80) == 0x00) return 1; else if ((*p1 & 0xE0) == 0xC0) @@ -248,48 +269,48 @@ struct putf8_traits } static code_t code(const mem_t *p) { - unsigned char *p1 = (unsigned char *)p; + const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p); if ((*p1 & 0x80) == 0x00) - return (code_t) *p1; + return *p1; else if ((*p1 & 0xE0) == 0xC0) - return ((p1[0] & 0x3f) << 6) | ((p1[1] & 0x3f)); + return static_cast<code_t>(((p1[0] & 0x3f) << 6) | (p1[1] & 0x3f)); else if ((*p1 & 0xF0) == 0xE0) - return ((p1[0] & 0x1f) << 12) | ((p1[1] & 0x3f) << 6) | ((p1[2] & 0x3f) << 0); + return static_cast<code_t>(((p1[0] & 0x1f) << 12) | ((p1[1] & 0x3f) << 6) | ((p1[2] & 0x3f) << 0)); else if ((*p1 & 0xF8) == 0xF0) - return ((p1[0] & 0x0f) << 18) | ((p1[1] & 0x3f) << 12) | ((p1[2] & 0x3f) << 6) | ((p1[3] & 0x3f) << 0); + return static_cast<code_t>(((p1[0] & 0x0f) << 18) | ((p1[1] & 0x3f) << 12) | ((p1[2] & 0x3f) << 6) | ((p1[3] & 0x3f) << 0)); else return *p1; // not correct } static void encode(const code_t c, mem_t *p) { - unsigned char *m = (unsigned char*)p; + unsigned char *m = reinterpret_cast<unsigned char *>(p); if (c < 0x0080) { - m[0] = c; + m[0] = static_cast<unsigned char>(c); } else if (c < 0x800) { - m[0] = 0xC0 | (c >> 6); - m[1] = 0x80 | (c & 0x3f); + m[0] = static_cast<unsigned char>(0xC0 | (c >> 6)); + m[1] = static_cast<unsigned char>(0x80 | (c & 0x3f)); } else if (c < 0x10000) { - m[0] = 0xE0 | (c >> 12); - m[1] = 0x80 | ((c>>6) & 0x3f); - m[2] = 0x80 | (c & 0x3f); + m[0] = static_cast<unsigned char>(0xE0 | (c >> 12)); + m[1] = static_cast<unsigned char>(0x80 | ((c>>6) & 0x3f)); + m[2] = static_cast<unsigned char>(0x80 | (c & 0x3f)); } else /* U+10000 U+1FFFFF */ { - m[0] = 0xF0 | (c >> 18); - m[1] = 0x80 | ((c>>12) & 0x3f); - m[2] = 0x80 | ((c>>6) & 0x3f); - m[3] = 0x80 | (c & 0x3f); + m[0] = static_cast<unsigned char>(0xF0 | (c >> 18)); + m[1] = static_cast<unsigned char>(0x80 | ((c>>12) & 0x3f)); + m[2] = static_cast<unsigned char>(0x80 | ((c>>6) & 0x3f)); + m[3] = static_cast<unsigned char>(0x80 | (c & 0x3f)); } } - static const mem_t *nthcode(const mem_t *p, const unsigned n) + static const mem_t *nthcode(const mem_t *p, const std::size_t n) { const mem_t *p1 = p; - int i = n; + std::size_t i = n; while (i-- > 0) p1 += codelen(p1); return p1; @@ -358,7 +379,7 @@ public: void cat(const pstring &s) { pcat(s); } void cat(const char *s) { pcat(s); } - void cat(const void *m, unsigned l) { pcat(m, l); } + void cat(const void *m, std::size_t l) { pcat(m, l); } void clear() { m_len = 0; *m_ptr = 0; } @@ -377,7 +398,7 @@ private: void pcopy(const pstring &from); void pcat(const char *s); void pcat(const pstring &s); - void pcat(const void *m, unsigned l); + void pcat(const void *m, std::size_t l); char *m_ptr; std::size_t m_size; @@ -397,7 +418,7 @@ namespace std const pstring::mem_t *string = s.cstr(); result_type result = 5381; for (pstring::mem_t c = *string; c != 0; c = *string++) - result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ c; + result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c); return result; } }; diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index c9b4379e590..2e2d19994e4 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -58,15 +58,14 @@ namespace plib bool set_from_string (const pstring &s) { \ static const char *strings = # __VA_ARGS__; \ int f = from_string_int(strings, s.cstr()); \ - if (f>=0) { m_v = (e) f; return true; } else { return false; } \ + if (f>=0) { m_v = static_cast<e>(f); return true; } else { return false; } \ } \ operator e() const {return m_v;} \ - int as_int() const {return (int) m_v;} \ bool operator==(const ename &rhs) const {return m_v == rhs.m_v;} \ - bool operator==(const e &rhs) const {return m_v == (int) rhs;} \ + bool operator==(const e &rhs) const {return m_v == rhs;} \ const pstring name() const { \ static const char *strings = # __VA_ARGS__; \ - return nthstr((int) m_v, strings); \ + return nthstr(static_cast<int>(m_v), strings); \ } \ private: e m_v; }; diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp index e8951d05aa9..f3f9b4c15ea 100644 --- a/src/lib/netlist/plib/putil.cpp +++ b/src/lib/netlist/plib/putil.cpp @@ -43,21 +43,20 @@ namespace plib pstring_vector_t::pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty) : std::vector<pstring>() { - int p = 0; - int pn; + pstring::iterator p = str.begin(); + pstring::iterator pn = str.find(onstr, p); - pn = str.find(onstr, p); - while (pn>=0) + while (pn != str.end()) { - pstring t = str.substr(p, pn - p); + pstring t = str.substr(p, pn); if (!ignore_empty || t.len() != 0) this->push_back(t); p = pn + onstr.len(); pn = str.find(onstr, p); } - if (p < (int) str.len()) + if (p != str.end()) { - pstring t = str.substr(p); + pstring t = str.substr(p, str.end()); if (!ignore_empty || t.len() != 0) this->push_back(t); } @@ -71,7 +70,7 @@ namespace plib unsigned i = 0; while (i<str.blen()) { - int p = -1; + std::size_t p = static_cast<std::size_t>(-1); for (std::size_t j=0; j < onstrl.size(); j++) { if (std::memcmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].blen())==0) @@ -80,7 +79,7 @@ namespace plib break; } } - if (p>=0) + if (p != static_cast<std::size_t>(-1)) { if (col != "") this->push_back(col); @@ -105,13 +104,13 @@ namespace plib { int cnt = 0; const char *cur = str; - int lx = strlen(x); + std::size_t lx = strlen(x); while (*str) { if (*str == ',') { - int l = str-cur; - if (l == lx) + std::ptrdiff_t l = str-cur; + if (static_cast<std::size_t>(l) == lx) if (strncmp(cur, x, lx) == 0) return cnt; } @@ -122,8 +121,8 @@ namespace plib } str++; } - int l = str-cur; - if (l == lx) + std::ptrdiff_t l = str-cur; + if (static_cast<std::size_t>(l) == lx) if (strncmp(cur, x, lx) == 0) return cnt; return -1; diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 39d10bcadb5..cc388cd3393 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -29,19 +29,20 @@ namespace plib return std::find(con.begin(), con.end(), elem) != con.end(); } + static constexpr const std::size_t npos = static_cast<std::size_t>(-1); template <class C> - int indexof(C &con, const typename C::value_type &elem) + std::size_t indexof(C &con, const typename C::value_type &elem) { auto it = std::find(con.begin(), con.end(), elem); if (it != con.end()) - return it - con.begin(); - return -1; + return static_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() + index, elem); + con.insert(con.begin() + static_cast<std::ptrdiff_t>(index), elem); } } diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 31cb8af00f6..92057688954 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -36,7 +36,7 @@ public: opt_help(*this, "h", "help", "display help and exit"), opt_grp2(*this, "Options for run and static commands", "These options apply to run and static commands."), opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"), - opt_grp3(*this, "Options for run command", "These options are only used by the run command."), + opt_grp3(*this, "Options for run command", "These options are only used by the run command."), opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."), opt_inp(*this, "i", "input", "", "input file to process (default is none)"), @@ -196,10 +196,10 @@ struct input_t static_cast<netlist::param_double_t*>(m_param)->setTo(m_value); break; case netlist::param_t::INTEGER: - static_cast<netlist::param_int_t*>(m_param)->setTo((int)m_value); + static_cast<netlist::param_int_t*>(m_param)->setTo(static_cast<int>(m_value)); break; case netlist::param_t::LOGIC: - static_cast<netlist::param_logic_t*>(m_param)->setTo((int) m_value); + static_cast<netlist::param_logic_t*>(m_param)->setTo(static_cast<bool>(m_value)); break; } } @@ -335,7 +335,7 @@ static void listdevices(tool_options_t &opts) if (t.second->name().startsWith(d->name())) { pstring tn(t.second->name().substr(d->name().len()+1)); - if (tn.find(".")<0) + if (tn.find(".") == tn.end()) terms.push_back(tn); } } @@ -345,7 +345,7 @@ static void listdevices(tool_options_t &opts) if (t.first.startsWith(d->name())) { pstring tn(t.first.substr(d->name().len()+1)); - if (tn.find(".")<0) + if (tn.find(".") == tn.end()) { terms.push_back(tn); pstring resolved = nt.setup().resolve_alias(t.first); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index a48323f265f..ea5fc450f2b 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -63,7 +63,7 @@ public: void write_sample(int sample) { m_data.len += m_fmt.block_align; - short ps = sample; /* 16 bit sample, FIXME: Endianess? */ + short ps = static_cast<short>(sample); /* 16 bit sample, FIXME: Endianess? */ m_f.write(&ps, sizeof(ps)); } @@ -77,14 +77,14 @@ private: struct riff_format_t { - char signature[4]; - unsigned fmt_length; - short format_tag; - short channels; - unsigned sample_rate; - unsigned bytes_per_second; - short block_align; - short bits_sample; + char signature[4]; + unsigned fmt_length; + short format_tag; + unsigned short channels; + unsigned sample_rate; + unsigned bytes_per_second; + unsigned short block_align; + unsigned short bits_sample; }; struct riff_data_t @@ -129,7 +129,7 @@ static void convert(nlwav_options_t &opts) plib::pifilestream fin(opts.opt_inp()); - double dt = 1.0 / (double) wo.sample_rate(); + double dt = 1.0 / static_cast<double>(wo.sample_rate()); double ct = dt; //double mean = 2.4; double amp = opts.opt_amp(); @@ -160,12 +160,12 @@ static void convert(nlwav_options_t &opts) minsam = std::min(minsam, outsam); n++; //mean = means / (double) n; - mean += 5.0 / (double) wo.sample_rate() * (outsam - mean); + mean += 5.0 / static_cast<double>(wo.sample_rate()) * (outsam - mean); } outsam = (outsam - mean) * amp; outsam = std::max(-32000.0, outsam); outsam = std::min(32000.0, outsam); - wo.write_sample((int) outsam); + wo.write_sample(static_cast<int>(outsam)); outsam = 0.0; lt = ct; ct += dt; @@ -195,7 +195,7 @@ static void convert(nlwav_options_t &opts) #endif } pout("Mean (low freq filter): {}\n", mean); - pout("Mean (static): {}\n", means / (double) n); + pout("Mean (static): {}\n", means / static_cast<double>(n)); pout("Amp + {}\n", 32000.0 / (maxsam- mean)); pout("Amp - {}\n", -32000.0 / (minsam- mean)); } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index e196649735e..36e39462c17 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -29,8 +29,8 @@ namespace netlist nl_double m_max_timestep; nl_double m_sor; bool m_dynamic; - int m_gs_loops; - int m_nr_loops; + unsigned m_gs_loops; + unsigned m_nr_loops; netlist_time m_nt_sync_delay; bool m_log_stats; }; @@ -60,7 +60,7 @@ public: void add(terminal_t *term, int net_other, bool sorted); - inline unsigned count() { return m_term.size(); } + inline std::size_t count() { return m_term.size(); } inline terminal_t **terms() { return m_term.data(); } inline int *net_other() { return m_net_other.data(); } @@ -71,7 +71,7 @@ public: void set_pointers(); - unsigned m_railstart; + std::size_t m_railstart; std::vector<unsigned> m_nz; /* all non zero for multiplication */ std::vector<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */ @@ -157,7 +157,7 @@ public: NETLIB_RESETI(); public: - int get_net_idx(net_t *net); + int get_net_idx(detail::net_t *net); plib::plog_base<NL_DEBUG> &log() { return netlist().log(); } @@ -174,10 +174,10 @@ protected: void update_dynamic(); virtual void vsetup(analog_net_t::list_t &nets) = 0; - virtual int vsolve_non_dynamic(const bool newton_raphson) = 0; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) = 0; netlist_time compute_next_timestep(const double cur_ts); - /* virtual */ void add_term(int net_idx, terminal_t *term); + /* virtual */ void add_term(std::size_t net_idx, terminal_t *term); template <typename T> void store(const T * RESTRICT V); @@ -230,17 +230,17 @@ T matrix_solver_t::delta(const T * RESTRICT V) * and thus belong into a different calculation. This applies to all solvers. */ - const unsigned iN = this->m_terms.size(); + std::size_t iN = this->m_terms.size(); T cerr = 0; for (unsigned i = 0; i < iN; i++) - cerr = std::max(cerr, std::abs(V[i] - (T) this->m_nets[i]->m_cur_Analog)); + cerr = std::max(cerr, std::abs(V[i] - static_cast<T>(this->m_nets[i]->m_cur_Analog))); return cerr; } template <typename T> void matrix_solver_t::store(const T * RESTRICT V) { - for (unsigned i = 0, iN=m_terms.size(); i < iN; i++) + for (std::size_t i = 0, iN=m_terms.size(); i < iN; i++) this->m_nets[i]->m_cur_Analog = V[i]; } @@ -257,8 +257,8 @@ void matrix_solver_t::build_LE_A() for (unsigned i=0; i < iN; i++) child.A(k,i) = 0.0; - const unsigned terms_count = m_terms[k]->count(); - const unsigned railstart = m_terms[k]->m_railstart; + const std::size_t terms_count = m_terms[k]->count(); + const std::size_t railstart = m_terms[k]->m_railstart; const nl_double * RESTRICT gt = m_terms[k]->gt(); { @@ -272,7 +272,7 @@ void matrix_solver_t::build_LE_A() const nl_double * RESTRICT go = m_terms[k]->go(); const int * RESTRICT net_other = m_terms[k]->net_other(); - for (unsigned i = 0; i < railstart; i++) + for (std::size_t i = 0; i < railstart; i++) child.A(k,net_other[i]) -= go[i]; } } @@ -289,15 +289,15 @@ void matrix_solver_t::build_LE_RHS() nl_double rhsk_a = 0.0; nl_double rhsk_b = 0.0; - const unsigned terms_count = m_terms[k]->count(); + const std::size_t terms_count = m_terms[k]->count(); const nl_double * RESTRICT go = m_terms[k]->go(); const nl_double * RESTRICT Idr = m_terms[k]->Idr(); const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog(); - for (unsigned i = 0; i < terms_count; i++) + for (std::size_t i = 0; i < terms_count; i++) rhsk_a = rhsk_a + Idr[i]; - for (unsigned i = m_terms[k]->m_railstart; i < terms_count; i++) + for (std::size_t i = m_terms[k]->m_railstart; i < terms_count; i++) //rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog(); rhsk_b = rhsk_b + go[i] * *other_cur_analog[i]; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index e4af64749e5..a4424970848 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -123,8 +123,8 @@ class matrix_solver_direct_t: public matrix_solver_t friend class matrix_solver_t; public: - matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const int size); - matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, const eSortType sort, const solver_parameters_t *params, const int size); + matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const unsigned size); + matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, const eSortType sort, const solver_parameters_t *params, const unsigned size); virtual ~matrix_solver_direct_t(); @@ -132,8 +132,8 @@ public: virtual void reset() override { matrix_solver_t::reset(); } protected: - virtual int vsolve_non_dynamic(const bool newton_raphson) override; - int solve_non_dynamic(const bool newton_raphson); + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; + unsigned solve_non_dynamic(const bool newton_raphson); inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } @@ -348,17 +348,17 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_back_subst( /* back substitution */ if (m_params.m_pivot) { - for (int j = kN - 1; j >= 0; j--) + for (unsigned j = kN; j-- > 0; ) { T tmp = 0; - for (unsigned k = j+1; k < kN; k++) + for (std::size_t k = j+1; k < kN; k++) tmp += A(j,k) * x[k]; x[j] = (RHS(j) - tmp) / A(j,j); } } else { - for (int j = kN - 1; j >= 0; j--) + for (unsigned j = kN; j-- > 0; ) { T tmp = 0; @@ -377,7 +377,7 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_back_subst( template <unsigned m_N, unsigned storage_N> -int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { nl_double new_V[storage_N]; // = { 0.0 }; @@ -400,7 +400,7 @@ int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_ } template <unsigned m_N, unsigned storage_N> -inline int matrix_solver_direct_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +inline unsigned matrix_solver_direct_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { build_LE_A<matrix_solver_direct_t>(); build_LE_RHS<matrix_solver_direct_t>(); @@ -414,7 +414,7 @@ inline int matrix_solver_direct_t<m_N, storage_N>::vsolve_non_dynamic(const bool template <unsigned m_N, unsigned storage_N> matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, - const solver_parameters_t *params, const int size) + const solver_parameters_t *params, const unsigned size) : matrix_solver_t(anetlist, name, ASCENDING, params) , m_dim(size) { @@ -432,7 +432,7 @@ matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(netlist_t &anetli template <unsigned m_N, unsigned storage_N> matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(netlist_t &anetlist, const pstring &name, - const eSortType sort, const solver_parameters_t *params, const int size) + const eSortType sort, const solver_parameters_t *params, const unsigned size) : matrix_solver_t(anetlist, name, sort, params) , m_dim(size) { diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h index 944e4bbcab2..3209ee5bd93 100644 --- a/src/lib/netlist/solver/nld_ms_direct1.h +++ b/src/lib/netlist/solver/nld_ms_direct1.h @@ -22,7 +22,7 @@ public: matrix_solver_direct1_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params) : matrix_solver_direct_t<1, 1>(anetlist, name, params, 1) {} - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; }; @@ -30,7 +30,7 @@ public: // matrix_solver - Direct1 // ---------------------------------------------------------------------------------------- -inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +inline unsigned matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) { build_LE_A<matrix_solver_direct1_t>(); build_LE_RHS<matrix_solver_direct1_t>(); diff --git a/src/lib/netlist/solver/nld_ms_direct2.h b/src/lib/netlist/solver/nld_ms_direct2.h index 3661d96b9fe..4a2525d1ef7 100644 --- a/src/lib/netlist/solver/nld_ms_direct2.h +++ b/src/lib/netlist/solver/nld_ms_direct2.h @@ -22,7 +22,7 @@ public: matrix_solver_direct2_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params) : matrix_solver_direct_t<2, 2>(anetlist, name, params, 2) {} - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; }; @@ -30,7 +30,7 @@ public: // matrix_solver - Direct2 // ---------------------------------------------------------------------------------------- -inline int matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +inline unsigned matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) { build_LE_A<matrix_solver_direct2_t>(); build_LE_RHS<matrix_solver_direct2_t>(); diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index cd2a749dec6..1f9e86bebd7 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -28,8 +28,8 @@ class matrix_solver_direct_t: public matrix_solver_t { public: - matrix_solver_direct_t(const solver_parameters_t *params, const int size); - matrix_solver_direct_t(const eSolverType type, const solver_parameters_t *params, const int size); + matrix_solver_direct_t(const solver_parameters_t *params, const unsigned size); + matrix_solver_direct_t(const eSolverType type, const solver_parameters_t *params, const unsigned size); virtual ~matrix_solver_direct_t(); @@ -568,7 +568,7 @@ void matrix_solver_direct_t<m_N, storage_N>::store( template <unsigned m_N, unsigned storage_N> -int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { nl_double new_V[storage_N]; // = { 0.0 }; @@ -602,7 +602,7 @@ inline int matrix_solver_direct_t<m_N, storage_N>::vsolve_non_dynamic(const bool } template <unsigned m_N, unsigned storage_N> -matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const solver_parameters_t *params, const int size) +matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const solver_parameters_t *params, const unsigned size) : matrix_solver_t(GAUSSIAN_ELIMINATION, params) , m_dim(size) , m_lp_fact(0) @@ -616,7 +616,7 @@ matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const solver_para } template <unsigned m_N, unsigned storage_N> -matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const eSolverType type, const solver_parameters_t *params, const int size) +matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const eSolverType type, const solver_parameters_t *params, const unsigned size) : matrix_solver_t(type, params) , m_dim(size) , m_lp_fact(0) diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index 014a7b6efec..8ce09a9ec78 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -33,7 +33,7 @@ class matrix_solver_GCR_t: public matrix_solver_t public: matrix_solver_GCR_t(netlist_t &anetlist, const pstring &name, - const solver_parameters_t *params, int size) + const solver_parameters_t *params, const unsigned size) : matrix_solver_t(anetlist, name, matrix_solver_t::ASCENDING, params) , m_dim(size) , m_proc(nullptr) @@ -47,7 +47,7 @@ public: inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } virtual void vsetup(analog_net_t::list_t &nets) override; - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; virtual void create_solver_code(plib::postream &strm) override; @@ -67,7 +67,7 @@ private: } unsigned m_dim; - std::vector<int> m_term_cr[storage_N]; + std::vector<unsigned> m_term_cr[storage_N]; mat_cr_t<storage_N> mat; nl_double m_A[storage_N * storage_N]; @@ -152,7 +152,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) { int other = this->m_terms[k]->net_other()[j]; for (unsigned i = mat.ia[k]; i < nz; i++) - if (other == (int) mat.ja[i]) + if (other == static_cast<int>(mat.ja[i])) { m_term_cr[k].push_back(i); break; @@ -164,7 +164,8 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) mat.ia[iN] = nz; mat.nz_num = nz; - this->log().verbose("Ops: {1} Occupancy ratio: {2}\n", ops, (double) nz / double (iN * iN)); + this->log().verbose("Ops: {1} Occupancy ratio: {2}\n", ops, + static_cast<double>(nz) / static_cast<double>(iN * iN)); // FIXME: Move me @@ -238,7 +239,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::create_solver_code(plib::postream &str template <unsigned m_N, unsigned storage_N> -int matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { const unsigned iN = this->N(); @@ -254,8 +255,8 @@ int matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra nl_double gtot_t = 0.0; nl_double RHS_t = 0.0; - const unsigned term_count = t->count(); - const unsigned railstart = t->m_railstart; + const std::size_t term_count = t->count(); + const std::size_t railstart = t->m_railstart; const nl_double * const RESTRICT gt = t->gt(); const nl_double * const RESTRICT go = t->go(); const nl_double * const RESTRICT Idr = t->Idr(); @@ -284,7 +285,7 @@ int matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra RHS_t += Idr[i]; } #endif - for (unsigned i = railstart; i < term_count; i++) + for (std::size_t i = railstart; i < term_count; i++) RHS_t += go[i] * *other_cur_analog[i]; RHS[k] = RHS_t; @@ -350,7 +351,7 @@ int matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra /* row n-1 */ new_V[iN - 1] = RHS[iN - 1] / m_A[mat.diag[iN - 1]]; - for (int j = iN - 2; j >= 0; j--) + for (unsigned j = iN - 1; j-- > 0;) { //__builtin_prefetch(&new_V[j-1], 1); //if (j>0)__builtin_prefetch(&m_A[mat.diag[j-1]], 0); diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index da0c239dd47..881f4c71fa2 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -28,7 +28,7 @@ class matrix_solver_GMRES_t: public matrix_solver_direct_t<m_N, storage_N> { public: - matrix_solver_GMRES_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, int size) + matrix_solver_GMRES_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const unsigned size) : matrix_solver_direct_t<m_N, storage_N>(anetlist, name, matrix_solver_t::ASCENDING, params, size) , m_use_iLU_preconditioning(true) , m_use_more_precise_stop_condition(false) @@ -41,13 +41,13 @@ public: } virtual void vsetup(analog_net_t::list_t &nets) override; - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; private: - int solve_ilu_gmres(nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy); + unsigned solve_ilu_gmres(nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy); - std::vector<int> m_term_cr[storage_N]; + std::vector<unsigned> m_term_cr[storage_N]; bool m_use_iLU_preconditioning; bool m_use_more_precise_stop_condition; @@ -97,7 +97,7 @@ void matrix_solver_GMRES_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) for (unsigned j=0; j< this->m_terms[k]->m_railstart;j++) { for (unsigned i = mat.ia[k]; i<nz; i++) - if (this->m_terms[k]->net_other()[j] == (int) mat.ja[i]) + if (this->m_terms[k]->net_other()[j] == static_cast<int>(mat.ja[i])) { m_term_cr[k].push_back(i); break; @@ -111,7 +111,7 @@ void matrix_solver_GMRES_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) } template <unsigned m_N, unsigned storage_N> -int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { const unsigned iN = this->N(); @@ -135,8 +135,8 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ nl_double gtot_t = 0.0; nl_double RHS_t = 0.0; - const unsigned term_count = this->m_terms[k]->count(); - const unsigned railstart = this->m_terms[k]->m_railstart; + const std::size_t term_count = this->m_terms[k]->count(); + const std::size_t railstart = this->m_terms[k]->m_railstart; const nl_double * const RESTRICT gt = this->m_terms[k]->gt(); const nl_double * const RESTRICT go = this->m_terms[k]->go(); const nl_double * const RESTRICT Idr = this->m_terms[k]->Idr(); @@ -144,13 +144,13 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ new_V[k] = this->m_nets[k]->m_cur_Analog; - for (unsigned i = 0; i < term_count; i++) + for (std::size_t i = 0; i < term_count; i++) { gtot_t = gtot_t + gt[i]; RHS_t = RHS_t + Idr[i]; } - for (unsigned i = railstart; i < term_count; i++) + for (std::size_t i = railstart; i < term_count; i++) RHS_t = RHS_t + go[i] * *other_cur_analog[i]; RHS[k] = RHS_t; @@ -158,7 +158,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ // add diagonal element m_A[mat.diag[k]] = gtot_t; - for (unsigned i = 0; i < railstart; i++) + for (std::size_t i = 0; i < railstart; i++) { const unsigned pi = m_term_cr[k][i]; m_A[pi] -= go[i]; @@ -168,12 +168,12 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ const nl_double accuracy = this->m_params.m_accuracy; - int mr = iN; + unsigned mr = iN; if (iN > 3 ) - mr = (int) sqrt(iN) * 2; - int iter = std::max(1, this->m_params.m_gs_loops); - int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy); - int failed = mr * iter; + mr = static_cast<unsigned>(std::sqrt(iN) * 2.0); + unsigned iter = std::max(1u, this->m_params.m_gs_loops); + unsigned gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy); + unsigned failed = mr * iter; this->m_iterative_total += gsl; this->m_stat_calculations++; @@ -210,7 +210,7 @@ inline void givens_mult( const T & c, const T & s, T & g0, T & g1 ) } template <unsigned m_N, unsigned storage_N> -int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy) +unsigned matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy) { /*------------------------------------------------------------------------- * The code below was inspired by code published by John Burkardt under @@ -266,7 +266,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT rho_delta = accuracy * rho_to_accuracy; } else - rho_delta = accuracy * std::sqrt((double) n) * m_accuracy_mult; + rho_delta = accuracy * std::sqrt(n) * m_accuracy_mult; for (unsigned itr = 0; itr < restart_max; itr++) { @@ -344,7 +344,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT /* Solve the system H * y = g */ /* x += m_v[j] * m_y[j] */ - for (int i = last_k; i >= 0; i--) + for (unsigned i = last_k + 1; i-- > 0;) { double tmp = m_g[i]; for (unsigned j = i + 1; j <= last_k; j++) diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index ffe59f93d21..2f3597f3a89 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -55,7 +55,7 @@ class matrix_solver_sm_t: public matrix_solver_t public: matrix_solver_sm_t(netlist_t &anetlist, const pstring &name, - const solver_parameters_t *params, const int size); + const solver_parameters_t *params, const unsigned size); virtual ~matrix_solver_sm_t(); @@ -63,8 +63,8 @@ public: virtual void reset() override { matrix_solver_t::reset(); } protected: - virtual int vsolve_non_dynamic(const bool newton_raphson) override; - int solve_non_dynamic(const bool newton_raphson); + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; + unsigned solve_non_dynamic(const bool newton_raphson); inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } @@ -155,19 +155,19 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_invert() /* FIXME: Singular matrix? */ const nl_double f = 1.0 / W(i,i); const auto * RESTRICT const p = m_terms[i]->m_nzrd.data(); - const unsigned e = m_terms[i]->m_nzrd.size(); + const std::size_t e = m_terms[i]->m_nzrd.size(); /* Eliminate column i from row j */ const auto * RESTRICT const pb = m_terms[i]->m_nzbd.data(); - const unsigned eb = m_terms[i]->m_nzbd.size(); - for (unsigned jb = 0; jb < eb; jb++) + const std::size_t eb = m_terms[i]->m_nzbd.size(); + for (std::size_t jb = 0; jb < eb; jb++) { const unsigned j = pb[jb]; const nl_double f1 = - W(j,i) * f; if (f1 != 0.0) { - for (unsigned k = 0; k < e; k++) + for (std::size_t k = 0; k < e; k++) W(j,p[k]) += W(i,p[k]) * f1; for (unsigned k = 0; k <= i; k ++) Ainv(j,k) += Ainv(i,k) * f1; @@ -175,11 +175,11 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_invert() } } /* up */ - for (int i = kN - 1; i >= 0; i--) + for (unsigned i = kN; i-- > 0; ) { /* FIXME: Singular matrix? */ const nl_double f = 1.0 / W(i,i); - for (int j = i - 1; j>=0; j--) + for (unsigned j = i; j-- > 0; ) { const nl_double f1 = - W(j,i) * f; if (f1 != 0.0) @@ -219,7 +219,7 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_compute_x( template <unsigned m_N, unsigned storage_N> -int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { static const bool incremental = true; static unsigned cnt = 0; @@ -309,7 +309,7 @@ int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raph } template <unsigned m_N, unsigned storage_N> -inline int matrix_solver_sm_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +inline unsigned matrix_solver_sm_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { build_LE_A<matrix_solver_sm_t>(); build_LE_RHS<matrix_solver_sm_t>(); @@ -323,7 +323,7 @@ inline int matrix_solver_sm_t<m_N, storage_N>::vsolve_non_dynamic(const bool new template <unsigned m_N, unsigned storage_N> matrix_solver_sm_t<m_N, storage_N>::matrix_solver_sm_t(netlist_t &anetlist, const pstring &name, - const solver_parameters_t *params, const int size) + const solver_parameters_t *params, const unsigned size) : matrix_solver_t(anetlist, name, NOSORT, params) , m_dim(size) { diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h index b7012f5532d..686280f7611 100644 --- a/src/lib/netlist/solver/nld_ms_sor.h +++ b/src/lib/netlist/solver/nld_ms_sor.h @@ -26,7 +26,7 @@ class matrix_solver_SOR_t: public matrix_solver_direct_t<m_N, storage_N> { public: - matrix_solver_SOR_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, int size) + matrix_solver_SOR_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const unsigned size) : matrix_solver_direct_t<m_N, storage_N>(anetlist, name, matrix_solver_t::ASCENDING, params, size) , m_lp_fact(*this, "m_lp_fact", 0) { @@ -35,7 +35,7 @@ public: virtual ~matrix_solver_SOR_t() {} virtual void vsetup(analog_net_t::list_t &nets) override; - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; private: state_var<nl_double> m_lp_fact; @@ -53,11 +53,11 @@ void matrix_solver_SOR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) } template <unsigned m_N, unsigned storage_N> -int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { const unsigned iN = this->N(); bool resched = false; - int resched_cnt = 0; + unsigned resched_cnt = 0; /* ideally, we could get an estimate for the spectral radius of * Inv(D - L) * U @@ -80,7 +80,7 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra nl_double gabs_t = 0.0; nl_double RHS_t = 0.0; - const unsigned term_count = this->m_terms[k]->count(); + const std::size_t term_count = this->m_terms[k]->count(); const nl_double * const RESTRICT gt = this->m_terms[k]->gt(); const nl_double * const RESTRICT go = this->m_terms[k]->go(); const nl_double * const RESTRICT Idr = this->m_terms[k]->Idr(); @@ -88,20 +88,20 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra new_V[k] = this->m_nets[k]->m_cur_Analog; - for (unsigned i = 0; i < term_count; i++) + for (std::size_t i = 0; i < term_count; i++) { gtot_t = gtot_t + gt[i]; RHS_t = RHS_t + Idr[i]; } - for (unsigned i = this->m_terms[k]->m_railstart; i < term_count; i++) + for (std::size_t i = this->m_terms[k]->m_railstart; i < term_count; i++) RHS_t = RHS_t + go[i] * *other_cur_analog[i]; RHS[k] = RHS_t; if (USE_GABS) { - for (unsigned i = 0; i < term_count; i++) + for (std::size_t i = 0; i < term_count; i++) gabs_t = gabs_t + std::abs(go[i]); gabs_t *= NL_FCONST(0.5); // derived by try and error @@ -138,11 +138,11 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra for (unsigned k = 0; k < iN; k++) { const int * RESTRICT net_other = this->m_terms[k]->net_other(); - const unsigned railstart = this->m_terms[k]->m_railstart; + const std::size_t railstart = this->m_terms[k]->m_railstart; const nl_double * RESTRICT go = this->m_terms[k]->go(); nl_double Idrive = 0.0; - for (unsigned i = 0; i < railstart; i++) + for (std::size_t i = 0; i < railstart; i++) Idrive = Idrive + go[i] * new_V[net_other[i]]; const nl_double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k]; diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index f53727cfe9b..f56a7028556 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -29,7 +29,7 @@ class matrix_solver_SOR_mat_t: public matrix_solver_direct_t<m_N, storage_N> public: - matrix_solver_SOR_mat_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, int size) + matrix_solver_SOR_mat_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const unsigned size) : matrix_solver_direct_t<m_N, storage_N>(anetlist, name, matrix_solver_t::DESCENDING, params, size) , m_Vdelta(*this, "m_Vdelta", 0.0) , m_omega(*this, "m_omega", params->m_sor) @@ -43,7 +43,7 @@ public: virtual void vsetup(analog_net_t::list_t &nets) override; - virtual int vsolve_non_dynamic(const bool newton_raphson) override; + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; private: state_var<nl_double[storage_N]> m_Vdelta; @@ -114,7 +114,7 @@ nl_double matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve() #endif template <unsigned m_N, unsigned storage_N> -int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { /* The matrix based code looks a lot nicer but actually is 30% slower than * the optimized code which works directly on the data structures. @@ -130,7 +130,7 @@ int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newto bool resched = false; - int resched_cnt = 0; + unsigned resched_cnt = 0; #if 0 @@ -181,9 +181,9 @@ int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newto nl_double Idrive = 0; const auto *p = this->m_terms[k]->m_nz.data(); - const unsigned e = this->m_terms[k]->m_nz.size(); + const std::size_t e = this->m_terms[k]->m_nz.size(); - for (unsigned i = 0; i < e; i++) + for (std::size_t i = 0; i < e; i++) Idrive = Idrive + this->A(k,p[i]) * new_v[p[i]]; const nl_double delta = m_omega * (this->RHS(k) - Idrive) / this->A(k,k); diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 33e94a207c3..55d9d630224 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -60,7 +60,7 @@ class matrix_solver_w_t: public matrix_solver_t friend class matrix_solver_t; public: - matrix_solver_w_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const int size); + matrix_solver_w_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, const unsigned size); virtual ~matrix_solver_w_t(); @@ -68,8 +68,8 @@ public: virtual void reset() override { matrix_solver_t::reset(); } protected: - virtual int vsolve_non_dynamic(const bool newton_raphson) override; - int solve_non_dynamic(const bool newton_raphson); + virtual unsigned vsolve_non_dynamic(const bool newton_raphson) override; + unsigned solve_non_dynamic(const bool newton_raphson); inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } @@ -164,12 +164,12 @@ void matrix_solver_w_t<m_N, storage_N>::LE_invert() /* FIXME: Singular matrix? */ const nl_double f = 1.0 / W(i,i); const auto * RESTRICT const p = m_terms[i]->m_nzrd.data(); - const unsigned e = m_terms[i]->m_nzrd.size(); + const size_t e = m_terms[i]->m_nzrd.size(); /* Eliminate column i from row j */ const auto * RESTRICT const pb = m_terms[i]->m_nzbd.data(); - const unsigned eb = m_terms[i]->m_nzbd.size(); + const size_t eb = m_terms[i]->m_nzbd.size(); for (unsigned jb = 0; jb < eb; jb++) { const auto j = pb[jb]; @@ -184,11 +184,11 @@ void matrix_solver_w_t<m_N, storage_N>::LE_invert() } } /* up */ - for (int i = kN - 1; i >= 0; i--) + for (unsigned i = kN; i-- > 0; ) { /* FIXME: Singular matrix? */ const nl_double f = 1.0 / W(i,i); - for (int j = i - 1; j>=0; j--) + for (unsigned j = i; j-- > 0; ) { const nl_double f1 = - W(j,i) * f; if (f1 != 0.0) @@ -227,7 +227,7 @@ void matrix_solver_w_t<m_N, storage_N>::LE_compute_x( template <unsigned m_N, unsigned storage_N> -int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) +unsigned matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { const auto iN = N(); @@ -320,7 +320,7 @@ int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphs /* Back substitution */ //inv(H) w = t w = H t nl_double t[storage_N]; // FIXME: convert to member - for (int j = rowcount - 1; j >= 0; j--) + for (unsigned j = rowcount; j-- > 0; ) { nl_double tmp = 0; const nl_double *pj = &H[j][j+1]; @@ -373,7 +373,7 @@ int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphs } template <unsigned m_N, unsigned storage_N> -inline int matrix_solver_w_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) +inline unsigned matrix_solver_w_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_raphson) { build_LE_A<matrix_solver_w_t>(); build_LE_RHS<matrix_solver_w_t>(); @@ -387,7 +387,7 @@ inline int matrix_solver_w_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt template <unsigned m_N, unsigned storage_N> matrix_solver_w_t<m_N, storage_N>::matrix_solver_w_t(netlist_t &anetlist, const pstring &name, - const solver_parameters_t *params, const int size) + const solver_parameters_t *params, const unsigned size) : matrix_solver_t(anetlist, name, NOSORT, params) ,m_cnt(0) , m_dim(size) diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 583ac904198..b26b7525b40 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -127,9 +127,9 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) net->set_solver(this); - for (core_terminal_t *p : net->m_core_terms) + for (auto &p : net->m_core_terms) { - log().debug("{1} {2} {3}\n", p->name(), net->name(), (int) net->isRailNet()); + log().debug("{1} {2} {3}\n", p->name(), net->name(), net->isRailNet()); switch (p->type()) { case terminal_t::TERMINAL: @@ -187,12 +187,12 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) void matrix_solver_t::setup_matrix() { - const unsigned iN = m_nets.size(); + const std::size_t iN = m_nets.size(); - for (unsigned k = 0; k < iN; k++) + for (std::size_t k = 0; k < iN; k++) { m_terms[k]->m_railstart = m_terms[k]->count(); - for (unsigned i = 0; i < m_rails_temp[k]->count(); i++) + for (std::size_t i = 0; i < m_rails_temp[k]->count(); i++) this->m_terms[k]->add(m_rails_temp[k]->terms()[i], m_rails_temp[k]->net_other()[i], false); m_rails_temp[k]->clear(); // no longer needed @@ -231,7 +231,7 @@ void matrix_solver_t::setup_matrix() for (unsigned k = 0; k < iN - 1; k++) for (unsigned i = k+1; i < iN; i++) { - if (((int) m_terms[k]->m_railstart - (int) m_terms[i]->m_railstart) * sort_order < 0) + if ((static_cast<int>(m_terms[k]->m_railstart) - static_cast<int>(m_terms[i]->m_railstart)) * sort_order < 0) { std::swap(m_terms[i], m_terms[k]); std::swap(m_nets[i], m_nets[k]); @@ -257,8 +257,8 @@ void matrix_solver_t::setup_matrix() t->m_nz.clear(); for (unsigned i = 0; i < t->m_railstart; i++) - if (!plib::container::contains(t->m_nz, other[i])) - t->m_nz.push_back(other[i]); + if (!plib::container::contains(t->m_nz, static_cast<unsigned>(other[i]))) + t->m_nz.push_back(static_cast<unsigned>(other[i])); t->m_nz.push_back(k); // add diagonal @@ -291,8 +291,8 @@ void matrix_solver_t::setup_matrix() } for (unsigned i = 0; i < t->m_railstart; i++) - if (!plib::container::contains(t->m_nzrd, other[i]) && other[i] >= (int) (k + 1)) - t->m_nzrd.push_back(other[i]); + if (!plib::container::contains(t->m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1)) + t->m_nzrd.push_back(static_cast<unsigned>(other[i])); /* and sort */ std::sort(t->m_nzrd.begin(), t->m_nzrd.end()); @@ -369,15 +369,15 @@ void matrix_solver_t::setup_matrix() void matrix_solver_t::update_inputs() { // avoid recursive calls. Inputs are updated outside this call - for (std::size_t i=0; i<m_inps.size(); i++) - m_inps[i]->set_Q(m_inps[i]->m_proxied_net->Q_Analog()); + for (auto &inp : m_inps) + inp->push(inp->m_proxied_net->Q_Analog()); } void matrix_solver_t::update_dynamic() { /* update all non-linear devices */ - for (std::size_t i=0; i < m_dynamic_devices.size(); i++) - m_dynamic_devices[i]->update_terminals(); + for (auto &dyn : m_dynamic_devices) + dyn->update_terminals(); } void matrix_solver_t::reset() @@ -419,8 +419,8 @@ void matrix_solver_t::solve_base() m_stat_vsolver_calls++; if (has_dynamic_devices()) { - int this_resched; - int newton_loops = 0; + unsigned this_resched; + unsigned newton_loops = 0; do { update_dynamic(); @@ -465,15 +465,15 @@ const netlist_time matrix_solver_t::solve() return next_time_step; } -int matrix_solver_t::get_net_idx(net_t *net) +int matrix_solver_t::get_net_idx(detail::net_t *net) { for (std::size_t k = 0; k < m_nets.size(); k++) if (m_nets[k] == net) - return k; + return static_cast<int>(k); return -1; } -void matrix_solver_t::add_term(int k, terminal_t *term) +void matrix_solver_t::add_term(std::size_t k, terminal_t *term) { if (term->m_otherterm->net().isRailNet()) { @@ -505,7 +505,7 @@ netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts) * FIXME: We should extend the logic to use either all nets or * only output nets. */ - for (unsigned k = 0, iN=m_terms.size(); k < iN; k++) + for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++) { analog_net_t *n = m_nets[k]; terms_t *t = m_terms[k]; @@ -550,28 +550,23 @@ void matrix_solver_t::log_stats() log().verbose(" ==> {1} nets", this->m_nets.size()); //, (*(*groups[i].first())->m_core_terms.first())->name()); log().verbose(" has {1} elements", this->has_dynamic_devices() ? "dynamic" : "no dynamic"); log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep"); - log().verbose(" {1:6.3} average newton raphson loops", (double) this->m_stat_newton_raphson / (double) this->m_stat_vsolver_calls); - log().verbose(" {1:10} invocations ({2:6} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average", + log().verbose(" {1:6.3} average newton raphson loops", + static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(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(), - this->m_stat_calculations() * 10 / (int) (this->netlist().time().as_double() * 10.0), + static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(), this->m_iterative_fail(), - 100.0 * (double) this->m_iterative_fail() / (double) this->m_stat_calculations(), - (double) this->m_iterative_total() / (double) this->m_stat_calculations()); + 100.0 * static_cast<double>(this->m_iterative_fail()) + / static_cast<double>(this->m_stat_calculations()), + static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations())); } } - - - - - // ---------------------------------------------------------------------------------------- // solver // ---------------------------------------------------------------------------------------- - - NETLIB_RESET(solver) { for (std::size_t i = 0; i < m_mat_solvers.size(); i++) @@ -596,7 +591,7 @@ NETLIB_UPDATE(solver) #if HAS_OPENMP && USE_OPENMP const std::size_t t_cnt = m_mat_solvers.size(); - if (m_parallel.Value()) + if (m_parallel()) { omp_set_num_threads(3); //omp_set_dynamic(0); @@ -634,7 +629,7 @@ NETLIB_UPDATE(solver) } template <int m_N, int storage_N> -std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(int size, const bool use_specific) +std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(unsigned size, const bool use_specific) { pstring solvername = plib::pfmt("Solver_{1}")(m_mat_solvers.size()); if (use_specific && m_N == 1) @@ -643,48 +638,48 @@ std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(int size, co return plib::make_unique<matrix_solver_direct2_t>(netlist(), solvername, &m_params); else { - if (size >= m_gs_threshold) + if (static_cast<int>(size) >= m_gs_threshold()) { - if (pstring("SOR_MAT").equals(m_iterative_solver)) + if (pstring("SOR_MAT").equals(m_iterative_solver())) { typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat; return plib::make_unique<solver_sor_mat>(netlist(), solvername, &m_params, size); } - else if (pstring("MAT_CR").equals(m_iterative_solver)) + else if (pstring("MAT_CR").equals(m_iterative_solver())) { typedef matrix_solver_GCR_t<m_N,storage_N> solver_mat; return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } - else if (pstring("MAT").equals(m_iterative_solver)) + else if (pstring("MAT").equals(m_iterative_solver())) { typedef matrix_solver_direct_t<m_N,storage_N> solver_mat; return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } - else if (pstring("SM").equals(m_iterative_solver)) + else if (pstring("SM").equals(m_iterative_solver())) { /* Sherman-Morrison Formula */ typedef matrix_solver_sm_t<m_N,storage_N> solver_mat; return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } - else if (pstring("W").equals(m_iterative_solver)) + else if (pstring("W").equals(m_iterative_solver())) { /* Woodbury Formula */ typedef matrix_solver_w_t<m_N,storage_N> solver_mat; return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } - else if (pstring("SOR").equals(m_iterative_solver)) + else if (pstring("SOR").equals(m_iterative_solver())) { typedef matrix_solver_SOR_t<m_N,storage_N> solver_GS; return plib::make_unique<solver_GS>(netlist(), solvername, &m_params, size); } - else if (pstring("GMRES").equals(m_iterative_solver)) + else if (pstring("GMRES").equals(m_iterative_solver())) { typedef matrix_solver_GMRES_t<m_N,storage_N> solver_GMRES; return plib::make_unique<solver_GMRES>(netlist(), solvername, &m_params, size); } else { - netlist().log().fatal("Unknown solver type: {1}\n", m_iterative_solver.Value()); + netlist().log().fatal("Unknown solver type: {1}\n", m_iterative_solver()); return nullptr; } } @@ -701,17 +696,18 @@ void NETLIB_NAME(solver)::post_start() std::vector<analog_net_t::list_t> groups; const bool use_specific = true; - m_params.m_pivot = m_pivot.Value(); - m_params.m_accuracy = m_accuracy.Value(); - m_params.m_gs_loops = m_gs_loops.Value(); - m_params.m_nr_loops = m_nr_loops.Value(); - m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay.Value()); - m_params.m_lte = m_lte.Value(); - m_params.m_sor = m_sor.Value(); + m_params.m_pivot = m_pivot(); + m_params.m_accuracy = m_accuracy(); + /* FIXME: Throw when negative */ + m_params.m_gs_loops = static_cast<unsigned>(m_gs_loops()); + m_params.m_nr_loops = static_cast<unsigned>(m_nr_loops()); + m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay()); + m_params.m_lte = m_lte(); + m_params.m_sor = m_sor(); - m_params.m_min_timestep = m_min_timestep.Value(); - m_params.m_dynamic = (m_dynamic.Value() == 1 ? true : false); - m_params.m_max_timestep = netlist_time::from_hz(m_freq.Value()).as_double(); + m_params.m_min_timestep = m_min_timestep(); + m_params.m_dynamic = (m_dynamic() == 1 ? true : false); + m_params.m_max_timestep = netlist_time::from_double(1.0 / m_freq()).as_double(); if (m_params.m_dynamic) { @@ -727,9 +723,9 @@ void NETLIB_NAME(solver)::post_start() // Override log statistics pstring p = plib::util::environment("NL_STATS"); if (p != "") - m_params.m_log_stats = (bool) p.as_long(); + m_params.m_log_stats = p.as_long(); else - m_params.m_log_stats = (bool) m_log_stats.Value(); + m_params.m_log_stats = m_log_stats(); netlist().log().verbose("Scanning net groups ..."); // determine net groups @@ -754,7 +750,7 @@ void NETLIB_NAME(solver)::post_start() for (auto & grp : groups) { std::unique_ptr<matrix_solver_t> ms; - std::size_t net_count = grp.size(); + unsigned net_count = static_cast<unsigned>(grp.size()); switch (net_count) { @@ -806,7 +802,7 @@ void NETLIB_NAME(solver)::post_start() break; #endif default: - netlist().log().warning("No specific solver found for netlist of size {1}", (unsigned) net_count); + netlist().log().warning("No specific solver found for netlist of size {1}", net_count); if (net_count <= 16) { ms = create_solver<0,16>(net_count, use_specific); @@ -841,10 +837,10 @@ void NETLIB_NAME(solver)::post_start() netlist().log().verbose(" ==> {2} nets", grp.size()); netlist().log().verbose(" has {1} elements", ms->has_dynamic_devices() ? "dynamic" : "no dynamic"); netlist().log().verbose(" has {1} elements", ms->has_timestep_devices() ? "timestep" : "no timestep"); - for (net_t *n : grp) + for (auto &n : grp) { netlist().log().verbose("Net {1}", n->name()); - for (const core_terminal_t *pcore : n->m_core_terms) + for (const auto &pcore : n->m_core_terms) { netlist().log().verbose(" {1}", pcore->name()); } diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index d683e627d3f..6fb7dad37ba 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -75,7 +75,7 @@ NETLIB_OBJECT(solver) void post_start(); void stop() override; - inline nl_double gmin() { return m_gmin.Value(); } + inline nl_double gmin() { return m_gmin(); } void create_solver_code(plib::postream &strm); @@ -111,7 +111,7 @@ private: solver_parameters_t m_params; template <int m_N, int storage_N> - std::unique_ptr<matrix_solver_t> create_solver(int size, bool use_specific); + std::unique_ptr<matrix_solver_t> create_solver(unsigned size, bool use_specific); }; } //namespace devices diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index d8a7401018e..5a238bfe9ba 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -153,12 +153,11 @@ double nl_convert_base_t::get_sp_unit(const pstring &unit) double nl_convert_base_t::get_sp_val(const pstring &sin) { - int p = sin.len() - 1; - while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9")) - p--; - pstring val = sin.substr(0,p + 1); - pstring unit = sin.substr(p + 1); - + auto p = sin.begin(); + while (p != sin.end() && (m_numberchars.find(*p) != m_numberchars.end())) + ++p; + pstring val = sin.left(p); + pstring unit = sin.substr(p); double ret = get_sp_unit(unit) * val.as_double(); return ret; } @@ -223,7 +222,7 @@ void nl_convert_spice_t::process_line(const pstring &line) switch (tt[0].code_at(0)) { case ';': - out("// {}\n", line.substr(1).cstr()); + out("// {}\n", line.substr(1)); break; case '*': out("// {}\n", line.substr(1).cstr()); @@ -249,7 +248,7 @@ void nl_convert_spice_t::process_line(const pstring &line) /* check for fourth terminal ... should be numeric net * including "0" or start with "N" (ltspice) */ - ATTR_UNUSED int nval =tt[4].as_long(&cerr); + ATTR_UNUSED long nval =tt[4].as_long(&cerr); pstring model; pstring pins ="CBE"; @@ -262,7 +261,7 @@ void nl_convert_spice_t::process_line(const pstring &line) { if (m[1].len() != 4) fprintf(stderr, "error with model desc %s\n", model.cstr()); - pins = m[1].left(3); + pins = m[1].left(m[1].begin() + 3); } add_device("QBJT_EB", tt[0], m[0]); add_term(tt[1], tt[0] + "." + pins.code_at(0)); diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h index ca086d5346b..209057a06d5 100644 --- a/src/lib/netlist/tools/nl_convert.h +++ b/src/lib/netlist/tools/nl_convert.h @@ -23,7 +23,7 @@ class nl_convert_base_t { public: - nl_convert_base_t() : out(m_buf) {} + nl_convert_base_t() : out(m_buf), m_numberchars("0123456789-+e.") {} virtual ~nl_convert_base_t() { m_nets.clear(); @@ -136,6 +136,7 @@ private: std::unordered_map<pstring, std::unique_ptr<pin_alias_t>> m_pins; static unit_t m_units[]; + pstring m_numberchars; }; |