summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib
diff options
context:
space:
mode:
author andreasnaive <andreasnaive@gmail.com>2019-03-25 23:13:40 +0100
committer andreasnaive <andreasnaive@gmail.com>2019-03-25 23:13:40 +0100
commitb380514764cf857469bae61c11143a19f79a74c5 (patch)
tree63c8012e262618f08a332da31dd714281aa2c5ed /src/lib/netlist/plib
parentc24473ddff715ecec2e258a6eb38960cf8c8e98e (diff)
Revert "conflict resolution (nw)"
This reverts commit c24473ddff715ecec2e258a6eb38960cf8c8e98e, reversing changes made to 009cba4fb8102102168ef32870892438327f3705.
Diffstat (limited to 'src/lib/netlist/plib')
-rw-r--r--src/lib/netlist/plib/gmres.h450
-rw-r--r--src/lib/netlist/plib/mat_cr.h530
-rw-r--r--src/lib/netlist/plib/palloc.cpp105
-rw-r--r--src/lib/netlist/plib/palloc.h513
-rw-r--r--src/lib/netlist/plib/parray.h126
-rw-r--r--src/lib/netlist/plib/pchrono.cpp4
-rw-r--r--src/lib/netlist/plib/pchrono.h52
-rw-r--r--src/lib/netlist/plib/pconfig.h51
-rw-r--r--src/lib/netlist/plib/pdynlib.cpp18
-rw-r--r--src/lib/netlist/plib/pdynlib.h15
-rw-r--r--src/lib/netlist/plib/pexception.cpp215
-rw-r--r--src/lib/netlist/plib/pexception.h214
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp121
-rw-r--r--src/lib/netlist/plib/pfmtlog.h50
-rw-r--r--src/lib/netlist/plib/pfunction.cpp32
-rw-r--r--src/lib/netlist/plib/pfunction.h4
-rw-r--r--src/lib/netlist/plib/plists.h122
-rw-r--r--src/lib/netlist/plib/pmain.cpp13
-rw-r--r--src/lib/netlist/plib/pmain.h20
-rw-r--r--src/lib/netlist/plib/pmatrix2d.h85
-rw-r--r--src/lib/netlist/plib/pmempool.h187
-rw-r--r--src/lib/netlist/plib/pomp.h28
-rw-r--r--src/lib/netlist/plib/poptions.cpp154
-rw-r--r--src/lib/netlist/plib/poptions.h161
-rw-r--r--src/lib/netlist/plib/pparser.cpp278
-rw-r--r--src/lib/netlist/plib/pparser.h107
-rw-r--r--src/lib/netlist/plib/ppmf.h28
-rw-r--r--src/lib/netlist/plib/pstate.cpp35
-rw-r--r--src/lib/netlist/plib/pstate.h67
-rw-r--r--src/lib/netlist/plib/pstream.cpp131
-rw-r--r--src/lib/netlist/plib/pstream.h408
-rw-r--r--src/lib/netlist/plib/pstring.cpp131
-rw-r--r--src/lib/netlist/plib/pstring.h457
-rw-r--r--src/lib/netlist/plib/ptime.h136
-rw-r--r--src/lib/netlist/plib/ptypes.h124
-rw-r--r--src/lib/netlist/plib/putil.cpp75
-rw-r--r--src/lib/netlist/plib/putil.h103
-rw-r--r--src/lib/netlist/plib/vector_ops.h151
38 files changed, 1497 insertions, 4004 deletions
diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h
deleted file mode 100644
index 2c357e97624..00000000000
--- a/src/lib/netlist/plib/gmres.h
+++ /dev/null
@@ -1,450 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * gmres.h
- *
- */
-
-#ifndef PLIB_GMRES_H_
-#define PLIB_GMRES_H_
-
-#include "mat_cr.h"
-#include "parray.h"
-#include "pconfig.h"
-#include "vector_ops.h"
-
-#include <algorithm>
-#include <cmath>
-
-
-namespace plib
-{
-
- template <typename FT, int SIZE>
- struct mat_precondition_ILU
- {
- using mat_type = plib::matrix_compressed_rows_t<FT, SIZE>;
-
- mat_precondition_ILU(std::size_t size, int ilu_scale = 4
- , std::size_t bw = plib::matrix_compressed_rows_t<FT, SIZE>::FILL_INFINITY)
- : m_mat(static_cast<typename mat_type::index_type>(size))
- , m_LU(static_cast<typename mat_type::index_type>(size))
- , m_use_iLU_preconditioning(ilu_scale >= 0)
- , m_ILU_scale(static_cast<std::size_t>(ilu_scale))
- , m_band_width(bw)
- {
- }
-
- template <typename M>
- void build(M &fill)
- {
- m_mat.build_from_fill_mat(fill, 0);
- if (m_use_iLU_preconditioning)
- {
- m_LU.gaussian_extend_fill_mat(fill);
- m_LU.build_from_fill_mat(fill, m_ILU_scale, m_band_width); // ILU(2)
- //m_LU.build_from_fill_mat(fill, 9999, 20); // Band matrix width 20
- }
- }
-
-
- template<typename R, typename V>
- void calc_rhs(R &rhs, const V &v)
- {
- m_mat.mult_vec(rhs, v);
- }
-
- void precondition()
- {
- if (m_use_iLU_preconditioning)
- {
- if (m_ILU_scale < 1)
- m_LU.raw_copy_from(m_mat);
- else
- m_LU.reduction_copy_from(m_mat);
- m_LU.incomplete_LU_factorization();
- }
- }
-
- template<typename V>
- void solve_LU_inplace(V &v)
- {
- if (m_use_iLU_preconditioning)
- {
- m_LU.solveLUx(v);
- }
- }
-
- PALIGNAS_VECTOROPT()
- mat_type m_mat;
- PALIGNAS_VECTOROPT()
- mat_type m_LU;
- bool m_use_iLU_preconditioning;
- std::size_t m_ILU_scale;
- std::size_t m_band_width;
- };
-
- template <typename FT, int SIZE>
- struct mat_precondition_diag
- {
- mat_precondition_diag(std::size_t size)
- : m_mat(size)
- , m_diag(size)
- , m_use_iLU_preconditioning(true)
- {
- }
-
- template <typename M>
- void build(M &fill)
- {
- m_mat.build_from_fill_mat(fill, 0);
- }
-
- template<typename R, typename V>
- void calc_rhs(R &rhs, const V &v)
- {
- m_mat.mult_vec(rhs, v);
- }
-
- void precondition()
- {
- if (m_use_iLU_preconditioning)
- {
- for (std::size_t i = 0; i< m_diag.size(); i++)
- {
- m_diag[i] = 1.0 / m_mat.A[m_mat.diag[i]];
- }
- }
- }
-
- template<typename V>
- void solve_LU_inplace(V &v)
- {
- if (m_use_iLU_preconditioning)
- {
- for (std::size_t i = 0; i< m_diag.size(); i++)
- v[i] = v[i] * m_diag[i];
- }
- }
-
- plib::matrix_compressed_rows_t<FT, SIZE> m_mat;
- plib::parray<FT, SIZE> m_diag;
- bool m_use_iLU_preconditioning;
- };
-
- /* FIXME: hardcoding RESTART to 20 becomes an issue on very large
- * systems.
- */
- template <typename FT, int SIZE, int RESTART = 20>
- struct gmres_t
- {
- public:
-
- using float_type = FT;
- // FIXME: dirty hack to make this compile
- static constexpr const std::size_t storage_N = plib::sizeabs<FT, SIZE>::ABS();
-
- gmres_t(std::size_t size)
- : residual(size)
- , Ax(size)
- , m_size(size)
- , m_use_more_precise_stop_condition(false)
- {
- }
-
- void givens_mult( const FT c, const FT s, FT & g0, FT & g1 )
- {
- const FT g0_last(g0);
-
- g0 = c * g0 - s * g1;
- g1 = s * g0_last + c * g1;
- }
-
- std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
-
- template <typename OPS, typename VT, typename VRHS>
- std::size_t solve(OPS &ops, VT &x, const VRHS & rhs, const std::size_t itr_max, float_type accuracy)
- {
- /*-------------------------------------------------------------------------
- * The code below was inspired by code published by John Burkardt under
- * the LPGL here:
- *
- * http://people.sc.fsu.edu/~jburkardt/cpp_src/mgmres/mgmres.html
- *
- * The code below was completely written from scratch based on the pseudo code
- * found here:
- *
- * http://de.wikipedia.org/wiki/GMRES-Verfahren
- *
- * The Algorithm itself is described in
- *
- * Yousef Saad,
- * Iterative Methods for Sparse Linear Systems,
- * Second Edition,
- * SIAM, 20003,
- * ISBN: 0898715342,
- * LC: QA188.S17.
- *
- *------------------------------------------------------------------------*/
-
- std::size_t itr_used = 0;
- double rho_delta = 0.0;
-
- const std::size_t n = size();
-
- ops.precondition();
-
- if (m_use_more_precise_stop_condition)
- {
- /* derive residual for a given delta x
- *
- * LU y = A dx
- *
- * ==> rho / accuracy = sqrt(y * y)
- *
- * This approach will approximate the iterative stop condition
- * based |xnew - xold| pretty precisely. But it is slow, or expressed
- * differently: The invest doesn't pay off.
- */
-
- vec_set_scalar(n, residual, accuracy);
- ops.calc_rhs(Ax, residual);
-
- ops.solve_LU_inplace(Ax);
-
- const float_type rho_to_accuracy = std::sqrt(vec_mult2<FT>(n, Ax)) / accuracy;
-
- rho_delta = accuracy * rho_to_accuracy;
- }
- else
- rho_delta = accuracy * std::sqrt(static_cast<FT>(n));
-
- /*
- * Using
- *
- * vec_set(n, x, rhs);
- * ops.solve_LU_inplace(x);
- *
- * to get a starting point for x degrades convergence speed compared
- * to using the last solution for x.
- *
- * LU x = b; solve for x;
- *
- */
-
- while (itr_used < itr_max)
- {
- std::size_t last_k = RESTART;
- float_type rho;
-
- ops.calc_rhs(Ax, x);
-
- vec_sub(n, residual, rhs, Ax);
-
- ops.solve_LU_inplace(residual);
-
- rho = std::sqrt(vec_mult2<FT>(n, residual));
-
- if (rho < rho_delta)
- return itr_used + 1;
-
- /* FIXME: The "+" is necessary to avoid link issues
- * on some systems / compiler versions. Issue reported by
- * AJR, no details known yet.
- */
- vec_set_scalar(RESTART+1, m_g, +constants<FT>::zero());
- m_g[0] = rho;
-
- //for (std::size_t i = 0; i < mr + 1; i++)
- // vec_set_scalar(mr, m_ht[i], NL_FCONST(0.0));
-
- vec_mult_scalar(n, m_v[0], residual, constants<FT>::one() / rho);
-
- for (std::size_t k = 0; k < RESTART; k++)
- {
- const std::size_t kp1 = k + 1;
-
- ops.calc_rhs(m_v[kp1], m_v[k]);
- ops.solve_LU_inplace(m_v[kp1]);
-
- for (std::size_t j = 0; j <= k; j++)
- {
- m_ht[j][k] = vec_mult<FT>(n, m_v[kp1], m_v[j]);
- vec_add_mult_scalar(n, m_v[kp1], m_v[j], -m_ht[j][k]);
- }
- m_ht[kp1][k] = std::sqrt(vec_mult2<FT>(n, m_v[kp1]));
-
- if (m_ht[kp1][k] != 0.0)
- vec_scale(n, m_v[kp1], constants<FT>::one() / m_ht[kp1][k]);
-
- for (std::size_t j = 0; j < k; j++)
- givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]);
-
- const float_type mu = 1.0 / std::hypot(m_ht[k][k], m_ht[kp1][k]);
-
- m_c[k] = m_ht[k][k] * mu;
- m_s[k] = -m_ht[kp1][k] * mu;
- m_ht[k][k] = m_c[k] * m_ht[k][k] - m_s[k] * m_ht[kp1][k];
- m_ht[kp1][k] = 0.0;
-
- givens_mult(m_c[k], m_s[k], m_g[k], m_g[kp1]);
-
- rho = std::abs(m_g[kp1]);
-
- itr_used = itr_used + 1;
-
- if (rho <= rho_delta)
- {
- last_k = k;
- break;
- }
- }
-
- if (last_k >= RESTART)
- /* didn't converge within accuracy */
- last_k = RESTART - 1;
-
- /* Solve the system H * y = g */
- /* x += m_v[j] * m_y[j] */
- for (std::size_t i = last_k + 1; i-- > 0;)
- {
- double tmp = m_g[i];
- for (std::size_t j = i + 1; j <= last_k; j++)
- tmp -= m_ht[i][j] * m_y[j];
- m_y[i] = tmp / m_ht[i][i];
- }
-
- for (std::size_t i = 0; i <= last_k; i++)
- vec_add_mult_scalar(n, x, m_v[i], m_y[i]);
-
- if (rho <= rho_delta)
- break;
-
- }
- return itr_used;
- }
-
- private:
-
- //typedef typename plib::mat_cr_t<FT, SIZE>::index_type mattype;
-
- plib::parray<float_type, SIZE> residual;
- plib::parray<float_type, SIZE> Ax;
-
- plib::parray<float_type, RESTART + 1> m_c; /* mr + 1 */
- plib::parray<float_type, RESTART + 1> m_g; /* mr + 1 */
- plib::parray<plib::parray<float_type, RESTART>, RESTART + 1> m_ht; /* (mr + 1), mr */
- plib::parray<float_type, RESTART + 1> m_s; /* mr + 1 */
- plib::parray<float_type, RESTART + 1> m_y; /* mr + 1 */
-
- //plib::parray<float_type, SIZE> m_v[RESTART + 1]; /* mr + 1, n */
- plib::parray<plib::parray<float_type, storage_N>, RESTART + 1> m_v; /* mr + 1, n */
-
- std::size_t m_size;
-
- bool m_use_more_precise_stop_condition;
-
-
- };
-
-
-#if 0
- /* Example of a Chebyshev iteration solver. This one doesn't work yet,
- * it needs to be extended for non-symmetric matrix operation and
- * depends on spectral radius estimates - which we don't have.
- *
- * Left here as another example.
- */
-
- template <typename FT, int SIZE>
- struct ch_t
- {
- public:
-
- typedef FT float_type;
- // FIXME: dirty hack to make this compile
- static constexpr const std::size_t storage_N = plib::sizeabs<FT, SIZE>::ABS();
-
- // Maximum iterations before a restart ...
- static constexpr const std::size_t restart_N = (storage_N > 0 ? 20 : 0);
-
- ch_t(std::size_t size)
- : residual(size)
- , Ax(size)
- , m_size(size)
- {
- }
-
- std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
-
- template <typename OPS, typename VT, typename VRHS>
- std::size_t solve(OPS &ops, VT &x0, const VRHS & rhs, const std::size_t iter_max, float_type accuracy)
- {
- /*-------------------------------------------------------------------------
- *
- *
- *------------------------------------------------------------------------*/
-
- ops.precondition();
-
- const FT lmax = 20.0;
- const FT lmin = 0.0001;
-
- const FT d = (lmax+lmin)/2.0;
- const FT c = (lmax-lmin)/2.0;
- FT alpha = 0;
- FT beta = 0;
- std::size_t itr_used = 0;
-
- plib::parray<FT, SIZE> x(size());
- plib::parray<FT, SIZE> p(size());
-
- plib::vec_set(size(), x, x0);
-
- ops.calc_rhs(Ax, x);
- vec_sub(size(), rhs, Ax, residual);
-
- FT rho_delta = accuracy * std::sqrt(static_cast<FT>(size()));
-
- rho_delta = 1e-9;
-
- for (int i = 0; i < iter_max; i++)
- {
- ops.solve_LU_inplace(residual);
- if (i==0)
- {
- vec_set(size(), p, residual);
- alpha = 2.0 / d;
- }
- else
- {
- beta = alpha * ( c / 2.0)*( c / 2.0);
- alpha = 1.0 / (d - beta);
- for (std::size_t k = 0; k < size(); k++)
- p[k] = residual[k] + beta * p[k];
- }
- plib::vec_add_mult_scalar(size(), p, alpha, x);
- ops.calc_rhs(Ax, x);
- plib::vec_sub(size(), rhs, Ax, residual);
- FT rho = std::sqrt(plib::vec_mult2<FT>(size(), residual));
- if (rho < rho_delta)
- break;
- itr_used++;
- }
- return itr_used;
- }
- private:
-
- //typedef typename plib::mat_cr_t<FT, SIZE>::index_type mattype;
-
- plib::parray<float_type, SIZE> residual;
- plib::parray<float_type, SIZE> Ax;
-
- std::size_t m_size;
-
- };
-#endif
-
-} // namespace plib
-
-#endif /* PLIB_GMRES_H_ */
diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h
deleted file mode 100644
index 4cc027f0d8f..00000000000
--- a/src/lib/netlist/plib/mat_cr.h
+++ /dev/null
@@ -1,530 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * mat_cr.h
- *
- * Compressed row format matrices
- *
- */
-
-#ifndef MAT_CR_H_
-#define MAT_CR_H_
-
-#include "palloc.h"
-#include "parray.h"
-#include "pconfig.h"
-#include "pomp.h"
-#include "pstate.h"
-#include "ptypes.h"
-#include "putil.h"
-
-#include <algorithm>
-#include <array>
-#include <cmath>
-#include <cstdlib>
-#include <type_traits>
-#include <vector>
-
-namespace plib
-{
-
- // FIXME: causes a crash with GMRES handler
- // template<typename T, int N, typename C = std::size_t>
-
- template<typename T, int N, typename C = uint16_t>
- struct matrix_compressed_rows_t
- {
- using index_type = C;
- using value_type = T;
-
- COPYASSIGNMOVE(matrix_compressed_rows_t, default)
-
- enum constants_e
- {
- FILL_INFINITY = 9999999
- };
-
- parray<index_type, N> diag; // diagonal index pointer n
- parray<index_type, (N == 0) ? 0 : (N < 0 ? N - 1 : N + 1)> row_idx; // row index pointer n + 1
- parray<index_type, N < 0 ? -N * N : N *N> col_idx; // column index array nz_num, initially (n * n)
- parray<value_type, N < 0 ? -N * N : N *N> A; // Matrix elements nz_num, initially (n * n)
- //parray<C, N < 0 ? -N * (N-1) / 2 : N * (N+1) / 2 > nzbd; // Support for gaussian elimination
- parray<std::vector<index_type>, N > nzbd; // Support for gaussian elimination
- // contains elimination rows below the diagonal
- // FIXME: convert to pvector
- std::vector<std::vector<index_type>> m_ge_par;
-
- index_type nz_num;
-
- explicit matrix_compressed_rows_t(const index_type n)
- : diag(n)
- , row_idx(n+1)
- , col_idx(n*n)
- , A(n*n)
- //, nzbd(n * (n+1) / 2)
- , nzbd(n)
- , nz_num(0)
- , m_size(n)
- {
- for (index_type i=0; i<n+1; i++)
- row_idx[i] = 0;
- }
-
- ~matrix_compressed_rows_t() = default;
-
- constexpr index_type size() const { return static_cast<index_type>((N>0) ? N : m_size); }
-
- void clear()
- {
- nz_num = 0;
- for (index_type i=0; i < size() + 1; i++)
- row_idx[i] = 0;
- }
-
- void set_scalar(const T scalar)
- {
- for (index_type i=0, e=nz_num; i<e; i++)
- A[i] = scalar;
- }
-
- void set(C r, C c, T val)
- {
- C ri = row_idx[r];
- while (ri < row_idx[r+1] && col_idx[ri] < c)
- ri++;
- // we have the position now;
- if (ri < row_idx[r+1] && col_idx[ri] == c)
- A[ri] = val;
- else
- {
- for (C i = nz_num; i>ri; i--)
- {
- A[i] = A[i-1];
- col_idx[i] = col_idx[i-1];
- }
- A[ri] = val;
- col_idx[ri] = c;
- for (C i = r + 1; i < size() + 1; i++)
- row_idx[i]++;
- nz_num++;
- if (c==r)
- diag[r] = ri;
- }
- }
-
- template <typename M>
- std::pair<std::size_t, std::size_t> gaussian_extend_fill_mat(M &fill)
- {
- std::size_t ops = 0;
- std::size_t fill_max = 0;
-
- for (std::size_t k = 0; k < fill.size(); k++)
- {
- ops++; // 1/A(k,k)
- for (std::size_t row = k + 1; row < fill.size(); row++)
- {
- if (fill[row][k] < FILL_INFINITY)
- {
- ops++;
- for (std::size_t col = k + 1; col < fill[row].size(); col++)
- //if (fill[k][col] < FILL_INFINITY)
- {
- auto f = std::min(fill[row][col], 1 + fill[row][k] + fill[k][col]);
- if (f < FILL_INFINITY)
- {
- if (f > fill_max)
- fill_max = f;
- ops += 2;
- }
- fill[row][col] = f;
- }
- }
- }
- }
- build_parallel_gaussian_execution_scheme(fill);
- return { fill_max, ops };
- }
-
- template <typename M>
- void build_from_fill_mat(const M &f, std::size_t max_fill = FILL_INFINITY - 1,
- std::size_t band_width = FILL_INFINITY)
- {
- C nz = 0;
- if (nz_num != 0)
- throw pexception("build_from_mat only allowed on empty CR matrix");
- for (std::size_t k=0; k < size(); k++)
- {
- row_idx[k] = nz;
-
- for (std::size_t j=0; j < size(); j++)
- if (f[k][j] <= max_fill && std::abs(static_cast<int>(k)-static_cast<int>(j)) <= static_cast<int>(band_width))
- {
- col_idx[nz] = static_cast<C>(j);
- if (j == k)
- diag[k] = nz;
- nz++;
- }
- }
-
- row_idx[size()] = nz;
- nz_num = nz;
- /* build nzbd */
-
- for (std::size_t k=0; k < size(); k++)
- {
- for (std::size_t j=k + 1; j < size(); j++)
- if (f[j][k] < FILL_INFINITY)
- nzbd[k].push_back(static_cast<C>(j));
- nzbd[k].push_back(0); // end of sequence
- }
- }
-
- template <typename V>
- void gaussian_elimination(V & RHS)
- {
- const std::size_t iN = size();
-
- for (std::size_t i = 0; i < iN - 1; i++)
- {
- std::size_t nzbdp = 0;
- std::size_t pi = diag[i];
- const value_type f = 1.0 / A[pi++];
- const std::size_t piie = row_idx[i+1];
- const auto &nz = nzbd[i];
-
- while (auto j = nz[nzbdp++])
- {
- // proceed to column i
-
- std::size_t pj = row_idx[j];
-
- while (col_idx[pj] < i)
- pj++;
-
- const value_type f1 = - A[pj++] * f;
-
- // subtract row i from j
- // fill-in available assumed, i.e. matrix was prepared
-
- for (std::size_t pii = pi; pii<piie; pii++)
- {
- while (col_idx[pj] < col_idx[pii])
- pj++;
- if (col_idx[pj] == col_idx[pii])
- A[pj++] += A[pii] * f1;
- }
-
- RHS[j] += f1 * RHS[i];
- }
- }
- }
-
- template <typename V>
- void gaussian_elimination_parallel(V & RHS)
- {
- // FIXME: move into solver creation ...
- plib::omp::set_num_threads(4);
- for (auto l = 0ul; l < m_ge_par.size(); l++)
- plib::omp::for_static(0ul, m_ge_par[l].size(), [this, &RHS, &l] (unsigned ll)
- {
- auto &i = m_ge_par[l][ll];
- {
- std::size_t nzbdp = 0;
- std::size_t pi = diag[i];
- const value_type f = 1.0 / A[pi++];
- const std::size_t piie = row_idx[i+1];
-
- while (auto j = nzbd[i][nzbdp++])
- {
- // proceed to column i
-
- std::size_t pj = row_idx[j];
-
- while (col_idx[pj] < i)
- pj++;
-
- const value_type f1 = - A[pj++] * f;
-
- // subtract row i from j
- // fill-in available assumed, i.e. matrix was prepared
- for (std::size_t pii = pi; pii<piie; pii++)
- {
- while (col_idx[pj] < col_idx[pii])
- pj++;
- if (col_idx[pj] == col_idx[pii])
- A[pj++] += A[pii] * f1;
- }
- RHS[j] += f1 * RHS[i];
- }
- }
- });
- }
-
- template <typename V1, typename V2>
- void gaussian_back_substitution(V1 &V, const V2 &RHS)
- {
- const std::size_t iN = size();
- /* row n-1 */
- V[iN - 1] = RHS[iN - 1] / A[diag[iN - 1]];
-
- for (std::size_t j = iN - 1; j-- > 0;)
- {
- value_type tmp = 0;
- const auto jdiag = diag[j];
- const std::size_t e = row_idx[j+1];
- for (std::size_t pk = jdiag + 1; pk < e; pk++)
- tmp += A[pk] * V[col_idx[pk]];
- V[j] = (RHS[j] - tmp) / A[jdiag];
- }
- }
-
- template <typename V1>
- void gaussian_back_substitution(V1 &V)
- {
- const std::size_t iN = size();
- /* row n-1 */
- V[iN - 1] = V[iN - 1] / A[diag[iN - 1]];
-
- for (std::size_t j = iN - 1; j-- > 0;)
- {
- value_type tmp = 0;
- const auto jdiag = diag[j];
- const std::size_t e = row_idx[j+1];
- for (std::size_t pk = jdiag + 1; pk < e; pk++)
- tmp += A[pk] * V[col_idx[pk]];
- V[j] = (V[j] - tmp) / A[jdiag];
- }
- }
-
-
- template <typename VTV, typename VTR>
- void mult_vec(VTR & res, const VTV & x)
- {
- /*
- * res = A * x
- */
-
- std::size_t row = 0;
- std::size_t k = 0;
- const std::size_t oe = nz_num;
-
- while (k < oe)
- {
- T tmp = 0.0;
- const std::size_t e = row_idx[row+1];
- for (; k < e; k++)
- tmp += A[k] * x[col_idx[k]];
- res[row++] = tmp;
- }
- }
-
- /* throws error if P(source)>P(destination) */
- template <typename LUMAT>
- void slim_copy_from(LUMAT & src)
- {
- for (std::size_t r=0; r<src.size(); r++)
- {
- C dp = row_idx[r];
- for (C sp = src.row_idx[r]; sp < src.row_idx[r+1]; sp++)
- {
- /* advance dp to source column and fill 0s if necessary */
- while (col_idx[dp] < src.col_idx[sp])
- A[dp++] = 0;
- if (row_idx[r+1] <= dp || col_idx[dp] != src.col_idx[sp])
- throw plib::pexception("slim_copy_from error");
- A[dp++] = src.A[sp];
- }
- /* fill remaining elements in row */
- while (dp < row_idx[r+1])
- A[dp++] = 0;
- }
- }
-
- /* only copies common elements */
- template <typename LUMAT>
- void reduction_copy_from(LUMAT & src)
- {
- C sp = 0;
- for (std::size_t r=0; r<src.size(); r++)
- {
- C dp = row_idx[r];
- while(sp < src.row_idx[r+1])
- {
- /* advance dp to source column and fill 0s if necessary */
- if (col_idx[dp] < src.col_idx[sp])
- A[dp++] = 0;
- else if (col_idx[dp] == src.col_idx[sp])
- A[dp++] = src.A[sp++];
- else
- sp++;
- }
- /* fill remaining elements in row */
- while (dp < row_idx[r+1])
- A[dp++] = 0;
- }
- }
-
- /* checks at all - may crash */
- template <typename LUMAT>
- void raw_copy_from(LUMAT & src)
- {
- for (std::size_t k = 0; k < nz_num; k++)
- A[k] = src.A[k];
- }
-
- void incomplete_LU_factorization()
- {
- /*
- * incomplete LU Factorization according to http://de.wikipedia.org/wiki/ILU-Zerlegung
- *
- * Result is stored in matrix LU
- *
- * For i = 1,...,N-1
- * For k = 0, ... , i - 1
- * If a[i,k] != 0
- * a[i,k] = a[i,k] / a[k,k]
- * For j = k + 1, ... , N - 1
- * If a[i,j] != 0
- * a[i,j] = a[i,j] - a[i,k] * a[k,j]
- * j=j+1
- * k=k+1
- * i=i+1
- *
- */
-
- for (std::size_t i = 1; i < size(); i++) // row i
- {
- const std::size_t p_i_end = row_idx[i + 1];
- // loop over all columns k left of diag in row i
- for (std::size_t i_k = row_idx[i]; i_k < diag[i]; i_k++)
- {
- const std::size_t k = col_idx[i_k];
- const std::size_t p_k_end = row_idx[k + 1];
- const T LUp_i_k = A[i_k] = A[i_k] / A[diag[k]];
-
- std::size_t k_j = diag[k] + 1;
- std::size_t i_j = i_k + 1;
-
- while (i_j < p_i_end && k_j < p_k_end ) // pj = (i, j)
- {
- // we can assume that within a row ja increases continuously */
- const std::size_t c_i_j = col_idx[i_j]; // row i, column j
- const std::size_t c_k_j = col_idx[k_j]; // row i, column j
- if (c_k_j < c_i_j)
- k_j++;
- else if (c_k_j == c_i_j)
- A[i_j++] -= LUp_i_k * A[k_j++];
- else
- i_j++;
- }
- }
- }
- }
-
- template <typename R>
- void solveLUx (R &r)
- {
- /*
- * Solve a linear equation Ax = r
- * where
- * A = L*U
- *
- * L unit lower triangular
- * U upper triangular
- *
- * ==> LUx = r
- *
- * ==> Ux = L⁻¹ r = w
- *
- * ==> r = Lw
- *
- * This can be solved for w using backwards elimination in L.
- *
- * Now Ux = w
- *
- * This can be solved for x using backwards elimination in U.
- *
- */
- for (std::size_t i = 1; i < size(); ++i )
- {
- T tmp = 0.0;
- const std::size_t j1 = row_idx[i];
- const std::size_t j2 = diag[i];
-
- for (std::size_t j = j1; j < j2; ++j )
- tmp += A[j] * r[col_idx[j]];
- r[i] -= tmp;
- }
- // i now is equal to n;
- for (std::size_t i = size(); i-- > 0; )
- {
- T tmp = 0.0;
- const std::size_t di = diag[i];
- const std::size_t j2 = row_idx[i+1];
- for (std::size_t j = di + 1; j < j2; j++ )
- tmp += A[j] * r[col_idx[j]];
- r[i] = (r[i] - tmp) / A[di];
- }
- }
- private:
- template <typename M>
- void build_parallel_gaussian_execution_scheme(const M &fill)
- {
- // calculate parallel scheme for gaussian elimination
- std::vector<std::vector<index_type>> rt(size());
- for (index_type k = 0; k < size(); k++)
- {
- for (index_type j = k+1; j < size(); j++)
- {
- if (fill[j][k] < FILL_INFINITY)
- {
- rt[k].push_back(j);
- }
- }
- }
-
- std::vector<index_type> levGE(size(), 0);
- index_type cl = 0;
-
- for (index_type k = 0; k < size(); k++ )
- {
- if (levGE[k] >= cl)
- {
- std::vector<index_type> t = rt[k];
- for (index_type j = k+1; j < size(); j++ )
- {
- bool overlap = false;
- // is there overlap
- if (plib::container::contains(t, j))
- overlap = true;
- for (auto &x : rt[j])
- if (plib::container::contains(t, x))
- {
- overlap = true;
- break;
- }
- if (overlap)
- levGE[j] = cl + 1;
- else
- {
- t.push_back(j);
- for (auto &x : rt[j])
- t.push_back(x);
- }
- }
- cl++;
- }
- }
-
- m_ge_par.clear();
- m_ge_par.resize(cl+1);
- for (index_type k = 0; k < size(); k++)
- m_ge_par[levGE[k]].push_back(k);
- }
-
- index_type m_size;
- };
-
-} // namespace plib
-
-#endif /* MAT_CR_H_ */
diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp
new file mode 100644
index 00000000000..e4d31985b23
--- /dev/null
+++ b/src/lib/netlist/plib/palloc.cpp
@@ -0,0 +1,105 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * palloc.c
+ *
+ */
+
+#include "pconfig.h"
+#include "palloc.h"
+#include "pfmtlog.h"
+
+#include <algorithm>
+
+namespace plib {
+
+//============================================================
+// Memory pool
+//============================================================
+
+mempool::mempool(size_t min_alloc, size_t min_align)
+: m_min_alloc(min_alloc), m_min_align(min_align)
+{
+}
+mempool::~mempool()
+{
+ for (auto & b : m_blocks)
+ {
+ if (b.m_num_alloc != 0)
+ {
+ fprintf(stderr, "Found block with %d dangling allocations\n", static_cast<int>(b.m_num_alloc));
+ }
+ ::operator delete(b.data);
+ }
+ m_blocks.clear();
+}
+
+size_t mempool::new_block()
+{
+ block b;
+ b.data = static_cast<char *>(::operator new(m_min_alloc));
+ b.cur_ptr = b.data;
+ b.m_free = m_min_alloc;
+ b.m_num_alloc = 0;
+ m_blocks.push_back(b);
+ return m_blocks.size() - 1;
+}
+
+size_t mempool::mininfosize()
+{
+ size_t sinfo = sizeof(mempool::info);
+#ifdef __APPLE__
+ size_t ma = 16;
+#else
+ size_t ma = 8;
+#endif
+ return ((std::max(m_min_align, sinfo) + ma - 1) / ma) * ma;
+}
+
+void *mempool::alloc(size_t size)
+{
+ size_t rs = (size + mininfosize() + m_min_align - 1) & ~(m_min_align - 1);
+ for (size_t bn=0; bn < m_blocks.size(); bn++)
+ {
+ auto &b = m_blocks[bn];
+ if (b.m_free > rs)
+ {
+ b.m_free -= rs;
+ b.m_num_alloc++;
+ auto i = reinterpret_cast<info *>(b.cur_ptr);
+ i->m_block = bn;
+ auto ret = reinterpret_cast<void *>(b.cur_ptr + mininfosize());
+ b.cur_ptr += rs;
+ return ret;
+ }
+ }
+ {
+ size_t bn = new_block();
+ auto &b = m_blocks[bn];
+ b.m_num_alloc = 1;
+ b.m_free = m_min_alloc - rs;
+ auto i = reinterpret_cast<info *>(b.cur_ptr);
+ i->m_block = bn;
+ auto ret = reinterpret_cast<void *>(b.cur_ptr + mininfosize());
+ b.cur_ptr += rs;
+ return ret;
+ }
+}
+
+void mempool::free(void *ptr)
+{
+ auto p = reinterpret_cast<char *>(ptr);
+
+ auto i = reinterpret_cast<info *>(p - mininfosize());
+ block *b = &m_blocks[i->m_block];
+ if (b->m_num_alloc == 0)
+ fprintf(stderr, "Argh .. double free\n");
+ else
+ {
+ //b->m_free = m_min_alloc;
+ //b->cur_ptr = b->data;
+ }
+ b->m_num_alloc--;
+}
+
+}
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index 15fede3a99b..a35bc50ff17 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -8,427 +8,172 @@
#ifndef PALLOC_H_
#define PALLOC_H_
-#include "pconfig.h"
#include "pstring.h"
-#include "ptypes.h"
-#include <cstddef>
-#include <cstdlib>
-#include <memory>
-#include <type_traits>
-#include <utility>
#include <vector>
-
-#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
-#include <malloc.h>
-#endif
+#include <memory>
namespace plib {
- //============================================================
- // Standard arena_deleter
- //============================================================
-
- template <typename P, typename T>
- struct arena_deleter
- {
- //using arena_storage_type = P *;
- using arena_storage_type = typename std::conditional<P::is_stateless, P, P *>::type;
- template <typename X, typename Y = void>
- typename std::enable_if<!X::is_stateless, X&>::type getref(X *x) { return *x;}
- template <typename X, typename Y = void *>
- typename std::enable_if<std::remove_pointer<X>::type::is_stateless, X&>::type
- getref(X &x, Y y = nullptr)
- {
- unused_var(y);
- return x;
- }
-
- constexpr arena_deleter(arena_storage_type a = arena_storage_type()) noexcept
- : m_a(a) { }
-
- template<typename PU, typename U, typename = typename
- std::enable_if<std::is_convertible< U*, T*>::value>::type>
- arena_deleter(const arena_deleter<PU, U> &rhs) noexcept : m_a(rhs.m_a) { }
-
- void operator()(T *p) //const
- {
- /* call destructor */
- p->~T();
- getref(m_a).deallocate(p);
- }
- //private:
- arena_storage_type m_a;
- };
-
- //============================================================
- // owned_ptr: smart pointer with ownership information
- //============================================================
-
- template <typename SC, typename D>
- class owned_ptr
- {
- public:
-
- using pointer = SC *;
- using element_type = SC;
- using deleter_type = D;
-
- owned_ptr()
- : m_ptr(nullptr), m_deleter(), m_is_owned(true) { }
-
- template <typename, typename>
- friend class owned_ptr;
-
- owned_ptr(pointer p, bool owned) noexcept
- : m_ptr(p), m_deleter(), m_is_owned(owned)
- { }
-
- owned_ptr(pointer p, bool owned, D deleter) noexcept
- : m_ptr(p), m_deleter(deleter), m_is_owned(owned)
- { }
-
-
- owned_ptr(const owned_ptr &r) = delete;
- owned_ptr & operator =(owned_ptr &r) = delete;
-
- template<typename DC, typename DC_D>
- owned_ptr & operator =(owned_ptr<DC, DC_D> &&r)
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = r.m_deleter;
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- owned_ptr(owned_ptr &&r) noexcept
- : m_ptr(r.m_ptr)
- , m_deleter(r.m_deleter)
- , m_is_owned(r.m_is_owned)
- {
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- }
-
- owned_ptr &operator=(owned_ptr &&r) noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = std::move(r.m_deleter);
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- template<typename DC, typename DC_D>
- owned_ptr(owned_ptr<DC, DC_D> &&r) noexcept
- : m_ptr(static_cast<pointer >(r.get()))
- , m_deleter(r.m_deleter)
- , m_is_owned(r.is_owned())
- {
- r.release();
- }
-
- ~owned_ptr() noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- {
- //delete m_ptr;
- m_deleter(m_ptr);
- }
- m_is_owned = false;
- m_ptr = nullptr;
- }
-
- /**
- * \brief Return @c true if the stored pointer is not null.
- */
- explicit operator bool() const noexcept { return m_ptr != nullptr; }
-
- pointer release()
- {
- pointer tmp = m_ptr;
- m_is_owned = false;
- m_ptr = nullptr;
- return tmp;
- }
-
- bool is_owned() const { return m_is_owned; }
-
- pointer operator ->() const noexcept { return m_ptr; }
- typename std::add_lvalue_reference<element_type>::type operator *() const noexcept { return *m_ptr; }
- pointer get() const noexcept { return m_ptr; }
-
- deleter_type& get_deleter() noexcept { return m_deleter; }
- const deleter_type& get_deleter() const noexcept { return m_deleter; }
-
- private:
- pointer m_ptr;
- D m_deleter;
- bool m_is_owned;
- };
-
- //============================================================
- // Arena allocator for use with containers
- //============================================================
-
- template <class ARENA, class T, std::size_t ALIGN = alignof(T)>
- class arena_allocator
+//============================================================
+// Memory allocation
+//============================================================
+
+template<typename T, typename... Args>
+T *palloc(Args&&... args)
+{
+ return new T(std::forward<Args>(args)...);
+}
+
+template<typename T>
+void pfree(T *ptr)
+{
+ delete ptr;
+}
+
+template<typename T>
+T* palloc_array(const std::size_t num)
+{
+ return new T[num]();
+}
+
+template<typename T>
+void pfree_array(T *ptr)
+{
+ delete [] ptr;
+}
+
+template<typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args)
+{
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template<typename BC, typename DC, typename... Args>
+static std::unique_ptr<BC> make_unique_base(Args&&... args)
+{
+ std::unique_ptr<BC> ret(new DC(std::forward<Args>(args)...));
+ return ret;
+}
+
+template <typename SC>
+class owned_ptr
+{
+private:
+ owned_ptr()
+ : m_ptr(nullptr), m_is_owned(true) { }
+public:
+ owned_ptr(SC *p, bool owned) noexcept
+ : m_ptr(p), m_is_owned(owned)
+ { }
+
+ owned_ptr(const owned_ptr &r) = delete;
+ owned_ptr & operator =(owned_ptr &r) = delete;
+
+ template<typename DC>
+ owned_ptr & operator =(owned_ptr<DC> &&r)
{
- public:
- using value_type = T;
- static constexpr const std::size_t align_size = ALIGN;
- using arena_type = ARENA;
-
- static_assert(align_size >= alignof(T) && (align_size % alignof(T)) == 0,
- "ALIGN must be greater than alignof(T) and a multiple");
-
- arena_allocator() noexcept
- : m_a(arena_type::instance())
- { }
-
- ~arena_allocator() noexcept = default;
-
- arena_allocator(const arena_allocator &rhs) noexcept = default;
- arena_allocator& operator=(const arena_allocator&) noexcept = delete;
-
- arena_allocator(arena_allocator&&) noexcept = default;
- arena_allocator& operator=(arena_allocator&&) = delete;
-
- arena_allocator(arena_type & a) noexcept : m_a(a)
- {
- }
-
- template <class U>
- arena_allocator(const arena_allocator<ARENA, U, ALIGN>& rhs) noexcept
- : m_a(rhs.m_a)
- {
- }
-
- template <class U> struct rebind
- {
- using other = arena_allocator<ARENA, U, ALIGN>;
- };
-
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T *>(m_a.allocate(ALIGN, sizeof(T) * n));
- }
-
- void deallocate(T* p, std::size_t n) noexcept
- {
- unused_var(n);
- m_a.deallocate(p);
- }
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- friend bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept;
-
- template <class AU, class U, std::size_t A> friend class arena_allocator;
- private:
- arena_type &m_a;
- };
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return A1 == A2 && rhs.m_a == lhs.m_a;
- }
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator!=(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return !(lhs == rhs);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
+ return *this;
}
- //============================================================
- // Memory allocation
- //============================================================
-
- struct aligned_arena
+ owned_ptr(owned_ptr &&r) noexcept
{
- static constexpr const bool is_stateless = true;
- template <class T, std::size_t ALIGN = alignof(T)>
- using allocator_type = arena_allocator<aligned_arena, T, ALIGN>;
-
- template <typename T>
- using owned_pool_ptr = plib::owned_ptr<T, arena_deleter<aligned_arena, T>>;
-
- static inline aligned_arena &instance()
- {
- static aligned_arena s_arena;
- return s_arena;
- }
-
- static inline void *allocate( size_t alignment, size_t size )
- {
- #if (USE_ALIGNED_ALLOCATION)
- #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
- return _aligned_malloc(size, alignment);
- #elif defined(__APPLE__)
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = nullptr;
- }
- return p;
- #else
- return aligned_alloc(alignment, size);
- #endif
- #else
- unused_var(alignment);
- return ::operator new(size);
- #endif
- }
-
- static inline void deallocate( void *ptr )
- {
- #if (USE_ALIGNED_ALLOCATION)
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- free(ptr);
- #else
- ::operator delete(ptr);
- #endif
- }
-
- template<typename T, typename... Args>
- owned_pool_ptr<T> make_poolptr(Args&&... args)
- {
- auto *mem = allocate(alignof(T), sizeof(T));
- return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<aligned_arena, T>(*this));
- }
-
- };
-
- template <typename T, std::size_t ALIGN>
- /*inline */ C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept
- {
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
- //auto t = reinterpret_cast<std::uintptr_t>(p);
- //if (t & (ALIGN-1))
- // printf("alignment error!");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
}
- template <typename T, std::size_t ALIGN>
- constexpr const T *assume_aligned_ptr(const T *p) noexcept
+ template<typename DC>
+ owned_ptr(owned_ptr<DC> &&r) noexcept
{
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_ptr = static_cast<SC *>(r.get());
+ m_is_owned = r.is_owned();
+ r.release();
}
- // FIXME: remove
- template<typename T, typename... Args>
- inline T *pnew(Args&&... args)
+ ~owned_ptr()
{
- auto *p = aligned_arena::allocate(alignof(T), sizeof(T));
- return new(p) T(std::forward<Args>(args)...);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
}
-
- template<typename T>
- inline void pdelete(T *ptr)
+ template<typename DC, typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- ptr->~T();
- aligned_arena::deallocate(ptr);
+ owned_ptr a;
+ DC *x = new DC(std::forward<Args>(args)...);
+ a.m_ptr = static_cast<SC *>(x);
+ return std::move(a);
}
-
- template <typename T>
- using unique_ptr = std::unique_ptr<T, arena_deleter<aligned_arena, T>>;
-
- template<typename T, typename... Args>
- plib::unique_ptr<T> make_unique(Args&&... args)
+ template<typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- return plib::unique_ptr<T>(pnew<T>(std::forward<Args>(args)...));
+ owned_ptr a;
+ a.m_ptr = new SC(std::forward<Args>(args)...);
+ return std::move(a);
}
-
-#if 0
- template<typename T, typename... Args>
- static owned_ptr<T> make_owned(Args&&... args)
+ SC * release()
{
- return owned_ptr<T>(pnew<T>(std::forward<Args>(args)...), true);
+ SC *tmp = m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
+ return tmp;
}
-#endif
-
-
- template <class T, std::size_t ALIGN = alignof(T)>
- using aligned_allocator = aligned_arena::allocator_type<T, ALIGN>;
-
- //============================================================
- // traits to determine alignment size and stride size
- // from types supporting alignment
- //============================================================
- PDEFINE_HAS_MEMBER(has_align, align_size);
+ bool is_owned() const { return m_is_owned; }
- template <typename T, typename X = void>
- struct align_traits
- {
- static constexpr const std::size_t align_size = alignof(std::max_align_t);
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
- };
+ SC * operator ->() const { return m_ptr; }
+ SC & operator *() const { return *m_ptr; }
+ SC * get() const { return m_ptr; }
+private:
+ SC *m_ptr;
+ bool m_is_owned;
+};
- template <typename T>
- struct align_traits<T, typename std::enable_if<has_align<T>::value, void>::type>
+class mempool
+{
+private:
+ struct block
{
- static constexpr const std::size_t align_size = T::align_size;
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
+ block() : m_num_alloc(0), m_free(0), cur_ptr(nullptr), data(nullptr) { }
+ std::size_t m_num_alloc;
+ std::size_t m_free;
+ char *cur_ptr;
+ char *data;
};
- //============================================================
- // Aligned vector
- //============================================================
+ size_t new_block();
+ size_t mininfosize();
- // FIXME: needs a separate file
- template <class T, std::size_t ALIGN = alignof(T)>
- class aligned_vector : public std::vector<T, aligned_allocator<T, ALIGN>>
+ struct info
{
- public:
- using base = std::vector<T, aligned_allocator<T, ALIGN>>;
+ info() : m_block(0) { }
+ size_t m_block;
+ };
- using reference = typename base::reference;
- using const_reference = typename base::const_reference;
- using pointer = typename base::pointer;
- using const_pointer = typename base::const_pointer;
- using size_type = typename base::size_type;
+ size_t m_min_alloc;
+ size_t m_min_align;
- using base::base;
+ std::vector<block> m_blocks;
- C14CONSTEXPR reference operator[](size_type i) noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
- constexpr const_reference operator[](size_type i) const noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
+public:
+ mempool(size_t min_alloc, size_t min_align);
+ ~mempool();
- pointer data() noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
- const_pointer data() const noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
+ void *alloc(size_t size);
+ void free(void *ptr);
- };
+};
-} // namespace plib
+}
#endif /* PALLOC_H_ */
diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h
deleted file mode 100644
index 1be37b908cd..00000000000
--- a/src/lib/netlist/plib/parray.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * parray.h
- *
- */
-
-#ifndef PARRAY_H_
-#define PARRAY_H_
-
-#include "palloc.h"
-#include "pconfig.h"
-#include "pexception.h"
-
-#include <array>
-#include <memory>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-namespace plib {
-
- template <typename FT, int SIZE>
- struct sizeabs
- {
- static constexpr std::size_t ABS() { return (SIZE < 0) ? static_cast<std::size_t>(0 - SIZE) : static_cast<std::size_t>(SIZE); }
- using container = typename std::array<FT, ABS()> ;
- };
-
- template <typename FT>
- struct sizeabs<FT, 0>
- {
- static constexpr const std::size_t ABS = 0;
- using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
- };
-
- /**
- * \brief Array with preallocated or dynamic allocation
- *
- * Passing SIZE > 0 has the same functionality as a std::array.
- * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the
- * constructor.
- * SIZE < 0 reserves std::abs(SIZE) elements statically in place allocated. The
- * actual size is passed in by the constructor.
- * This array is purely intended for HPC application where depending on the
- * architecture a preference dynamic/static has to be made.
- *
- * This struct is not intended to be a full replacement to std::array.
- * It is a subset to enable switching between dynamic and static allocation.
- * I consider > 10% performance difference to be a use case.
- */
-
- template <typename FT, int SIZE>
- struct parray
- {
- public:
- static constexpr std::size_t SIZEABS() { return sizeabs<FT, SIZE>::ABS(); }
-
- using base_type = typename sizeabs<FT, SIZE>::container;
- using size_type = typename base_type::size_type;
- using reference = typename base_type::reference;
- using const_reference = typename base_type::const_reference;
- using value_type = typename base_type::value_type;
-
- template <int X = SIZE >
- parray(size_type size, typename std::enable_if<X==0, int>::type = 0)
- : m_a(size), m_size(size)
- {
- }
-
-#if 1
- /* allow construction in fixed size arrays */
- template <int X = SIZE >
- parray(typename std::enable_if<(X > 0), int>::type = 0)
- : m_size(X)
- {
- }
-#endif
- template <int X = SIZE >
- parray(size_type size, typename std::enable_if<X!=0, int>::type = 0)
- : m_size(size)
- {
- if (SIZE < 0 && size > SIZEABS())
- throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZEABS()));
- else if (SIZE > 0 && size != SIZEABS())
- throw plib::pexception("parray: size error");
- }
-
- inline size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); }
-
- constexpr size_type max_size() const noexcept { return base_type::max_size(); }
-
- bool empty() const noexcept { return size() == 0; }
-
-#if 0
- reference operator[](size_type i) /*noexcept*/
- {
- if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
- return m_a[i];
- }
- const_reference operator[](size_type i) const /*noexcept*/
- {
- if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
- return m_a[i];
- }
-#else
- C14CONSTEXPR reference operator[](size_type i) noexcept
- {
- return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
- }
- constexpr const_reference operator[](size_type i) const noexcept
- {
- return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
- }
-#endif
- FT * data() noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
- const FT * data() const noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
-
- private:
- PALIGNAS_VECTOROPT()
- base_type m_a;
- size_type m_size;
- };
-} // namespace plib
-
-#endif /* PARRAY_H_ */
diff --git a/src/lib/netlist/plib/pchrono.cpp b/src/lib/netlist/plib/pchrono.cpp
index 953d948e062..971d19b3645 100644
--- a/src/lib/netlist/plib/pchrono.cpp
+++ b/src/lib/netlist/plib/pchrono.cpp
@@ -49,5 +49,5 @@ exact_ticks::type exact_ticks::per_second()
#endif
-} // namespace chrono
-} // namespace plib
+}
+}
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index 8ce0eca23b3..a229128e7b8 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -9,17 +9,16 @@
#define PCHRONO_H_
#include "pconfig.h"
-#include "ptypes.h"
-#include <chrono>
#include <cstdint>
+#include <chrono>
namespace plib {
namespace chrono {
template <typename T>
struct sys_ticks
{
- using type = typename T::rep;
+ typedef typename T::rep type;
static inline type start() { return T::now().time_since_epoch().count(); }
static inline type stop() { return T::now().time_since_epoch().count(); }
static inline constexpr type per_second() { return T::period::den / T::period::num; }
@@ -146,7 +145,7 @@ namespace chrono {
struct counter
{
counter() : m_count(0) { }
- using type = uint_least64_t;
+ typedef uint_least64_t type;
type operator()() const { return m_count; }
void inc() { ++m_count; }
void reset() { m_count = 0; }
@@ -158,7 +157,7 @@ namespace chrono {
template<>
struct counter<false>
{
- using type = uint_least64_t;
+ typedef uint_least64_t type;
constexpr type operator()() const { return 0; }
void inc() const { }
void reset() const { }
@@ -169,28 +168,15 @@ namespace chrono {
template< typename T, bool enabled_ = true>
struct timer
{
- using type = typename T::type;
- using ctype = uint_least64_t;
- constexpr static bool enabled = enabled_;
-
- struct guard_t
- {
- guard_t() = delete;
- guard_t(timer &m) noexcept : m_m(m) { m_m.m_time -= T::start(); }
- ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; }
-
- COPYASSIGNMOVE(guard_t, default)
-
- private:
- timer &m_m;
- };
-
- friend struct guard_t;
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
timer() : m_time(0), m_count(0) { }
type operator()() const { return m_time; }
+ void start() { m_time -= T::start(); }
+ void stop() { m_time += T::stop(); ++m_count; }
void reset() { m_time = 0; m_count = 0; }
type average() const { return (m_count == 0) ? 0 : m_time / m_count; }
type total() const { return m_time; }
@@ -199,7 +185,7 @@ namespace chrono {
double as_seconds() const { return static_cast<double>(total())
/ static_cast<double>(T::per_second()); }
- guard_t guard() { return guard_t(*this); }
+ constexpr static bool enabled = enabled_;
private:
type m_time;
ctype m_count;
@@ -208,31 +194,19 @@ namespace chrono {
template<typename T>
struct timer<T, false>
{
- using type = typename T::type;
- using ctype = uint_least64_t;
-
- struct guard_t
- {
- guard_t() = default;
- COPYASSIGNMOVE(guard_t, default)
- /* using default constructor will trigger warning on
- * unused local variable.
- */
- // NOLINTNEXTLINE(modernize-use-equals-default)
- ~guard_t() { }
- };
-
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
constexpr type operator()() const { return 0; }
+ void start() const { }
+ void stop() const { }
void reset() const { }
constexpr type average() const { return 0; }
constexpr type total() const { return 0; }
constexpr ctype count() const { return 0; }
constexpr double as_seconds() const { return 0.0; }
constexpr static bool enabled = false;
- guard_t guard() { return guard_t(); }
};
-
} // namespace chrono
} // namespace plib
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index d66b342f815..0200c305ecd 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -21,46 +21,18 @@
* if PHAS_RDTSCP == 1
*/
#ifndef PUSE_ACCURATE_STATS
-#define PUSE_ACCURATE_STATS (0)
+#define PUSE_ACCURATE_STATS (1)
#endif
/*
* Set this to one if you want to use 128 bit int for ptime.
- * This is about 5% slower on a kaby lake processor.
+ * This is for tests only.
*/
#ifndef PHAS_INT128
#define PHAS_INT128 (0)
#endif
-/*
- * Set this to one if you want to use aligned storage optimizations.
- */
-
-#ifndef USE_ALIGNED_OPTIMIZATIONS
-#define USE_ALIGNED_OPTIMIZATIONS (0)
-#endif
-
-#define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS)
-#define USE_ALIGNED_HINTS (USE_ALIGNED_OPTIMIZATIONS)
-/*
- * Standard alignment macros
- */
-
-#define PALIGN_CACHELINE (64)
-#define PALIGN_VECTOROPT (64)
-
-#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE)
-#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT)
-
-/* Breaks mame build on windows due to -Wattribute
- * FIXME: no error on cross-compile - need further checks */
-#if defined(_WIN32) && defined(__GNUC__)
-#define PALIGNAS(x)
-#else
-#define PALIGNAS(x) alignas(x)
-#endif
-
/*============================================================
* Check for CPP Version
*
@@ -75,13 +47,6 @@
*
*============================================================*/
-#ifndef NVCCBUILD
-#define NVCCBUILD (0)
-#endif
-
-#if NVCCBUILD
-#define C14CONSTEXPR
-#else
#if __cplusplus == 201103L
#define C14CONSTEXPR
#elif __cplusplus == 201402L
@@ -93,7 +58,6 @@
#else
#error "C++ version not supported"
#endif
-#endif
#ifndef PHAS_INT128
#define PHAS_INT128 (0)
@@ -104,6 +68,17 @@ typedef __uint128_t UINT128;
typedef __int128_t INT128;
#endif
+#if defined(__GNUC__)
+#ifdef RESTRICT
+#undef RESTRICT
+#endif
+#define RESTRICT __restrict__
+#define ATTR_UNUSED __attribute__((__unused__))
+#else
+#define RESTRICT
+#define ATTR_UNUSED
+#endif
+
//============================================================
// Standard defines
//============================================================
diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp
index 0d32bead51d..13827eaf24c 100644
--- a/src/lib/netlist/plib/pdynlib.cpp
+++ b/src/lib/netlist/plib/pdynlib.cpp
@@ -25,7 +25,7 @@ CHAR *astring_from_utf8(const char *utf8string)
// convert UTF-16 to "ANSI code page" string
char_count = WideCharToMultiByte(CP_ACP, 0, wstring, -1, nullptr, 0, nullptr, nullptr);
- result = new CHAR[char_count];
+ result = palloc_array<CHAR>(char_count);
if (result != nullptr)
WideCharToMultiByte(CP_ACP, 0, wstring, -1, result, char_count, nullptr, nullptr);
@@ -39,7 +39,7 @@ WCHAR *wstring_from_utf8(const char *utf8string)
// convert MAME string (UTF-8) to UTF-16
char_count = MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, nullptr, 0);
- result = new WCHAR[char_count];
+ result = palloc_array<WCHAR>(char_count);
if (result != nullptr)
MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, result, char_count);
@@ -58,7 +58,7 @@ WCHAR *wstring_from_utf8(const char *utf8string)
#endif
namespace plib {
-dynlib::dynlib(const pstring &libname)
+dynlib::dynlib(const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
#ifdef _WIN32
@@ -72,7 +72,7 @@ dynlib::dynlib(const pstring &libname)
m_isLoaded = true;
//else
// fprintf(stderr, "win: library <%s> not found!\n", libname.c_str());
- delete [] buffer;
+ pfree_array(buffer);
#elif defined(EMSCRIPTEN)
//no-op
#else
@@ -88,11 +88,9 @@ dynlib::dynlib(const pstring &libname)
#endif
}
-dynlib::dynlib(const pstring &path, const pstring &libname)
+dynlib::dynlib(const pstring path, const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
- // FIXME: implement path search
- plib::unused_var(path);
// printf("win: loading <%s>\n", libname.c_str());
#ifdef _WIN32
TCHAR *buffer = tstring_from_utf8(libname.c_str());
@@ -106,7 +104,7 @@ dynlib::dynlib(const pstring &path, const pstring &libname)
{
//printf("win: library <%s> not found!\n", libname.c_str());
}
- delete [] buffer;
+ pfree_array(buffer);
#elif defined(EMSCRIPTEN)
//no-op
#else
@@ -141,7 +139,7 @@ bool dynlib::isLoaded() const
return m_isLoaded;
}
-void *dynlib::getsym_p(const pstring &name)
+void *dynlib::getsym_p(const pstring name)
{
#ifdef _WIN32
return (void *) GetProcAddress((HMODULE) m_lib, name.c_str());
@@ -150,4 +148,4 @@ void *dynlib::getsym_p(const pstring &name)
#endif
}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pdynlib.h b/src/lib/netlist/plib/pdynlib.h
index 1454c053298..7c9412593c9 100644
--- a/src/lib/netlist/plib/pdynlib.h
+++ b/src/lib/netlist/plib/pdynlib.h
@@ -8,31 +8,28 @@
#define PDYNLIB_H_
#include "pstring.h"
-#include "ptypes.h"
namespace plib {
// ----------------------------------------------------------------------------------------
// pdynlib: dynamic loading of libraries ...
// ----------------------------------------------------------------------------------------
-class dynlib : public nocopyassignmove
+class dynlib
{
public:
- explicit dynlib(const pstring &libname);
- dynlib(const pstring &path, const pstring &libname);
-
+ explicit dynlib(const pstring libname);
+ dynlib(const pstring path, const pstring libname);
~dynlib();
- COPYASSIGNMOVE(dynlib, delete)
bool isLoaded() const;
template <typename T>
- T getsym(const pstring &name)
+ T getsym(const pstring name)
{
return reinterpret_cast<T>(getsym_p(name));
}
private:
- void *getsym_p(const pstring &name);
+ void *getsym_p(const pstring name);
bool m_isLoaded;
void *m_lib;
@@ -67,6 +64,6 @@ private:
calltype m_sym;
};
-} // namespace plib
+}
#endif /* PSTRING_H_ */
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
index 8d6907d66f2..a4ed8f367e0 100644
--- a/src/lib/netlist/plib/pexception.cpp
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -9,7 +9,6 @@
#include "pfmtlog.h"
#include <cfenv>
-#include <iostream>
#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__)
#define HAS_FEENABLE_EXCEPT (1)
@@ -18,113 +17,127 @@
#endif
namespace plib {
-
- //============================================================
- // terminate
- //============================================================
-
- void terminate(const pstring &msg) noexcept
- {
- std::cerr << msg.c_str() << "\n";
- std::terminate();
- }
-
-
- //============================================================
- // Exceptions
- //============================================================
-
- pexception::pexception(const pstring &text)
- : m_text(text)
- {
- }
-
-
- file_e::file_e(const pstring &fmt, const pstring &filename)
- : pexception(pfmt(fmt)(filename))
- {
- }
-
-
- file_open_e::file_open_e(const pstring &filename)
- : file_e("File open failed: {}", filename)
- {
- }
-
-
- file_read_e::file_read_e(const pstring &filename)
- : file_e("File read failed: {}", filename)
- {
- }
-
-
- file_write_e::file_write_e(const pstring &filename)
- : file_e("File write failed: {}", filename)
+//============================================================
+// Exceptions
+//============================================================
+
+pexception::pexception(const pstring &text)
+: m_text(text)
+{
+}
+
+pexception::~pexception() noexcept
+{
+}
+
+file_e::file_e(const pstring &fmt, const pstring &filename)
+ : pexception(pfmt(fmt)(filename))
+{
+}
+
+file_e::~file_e() noexcept
+{
+}
+
+file_open_e::file_open_e(const pstring &filename)
+ : file_e("File open failed: {}", filename)
+{
+}
+
+file_open_e::~file_open_e() noexcept
+{
+
+}
+
+file_read_e::file_read_e(const pstring &filename)
+ : file_e("File read failed: {}", filename)
+{
+}
+
+file_read_e::~file_read_e() noexcept
+{
+
+}
+
+file_write_e::file_write_e(const pstring &filename)
+ : file_e("File write failed: {}", filename)
+{
+}
+
+file_write_e::~file_write_e() noexcept
+{
+}
+
+null_argument_e::null_argument_e(const pstring &argument)
+ : pexception(pfmt("Null argument passed: {}")(argument))
+{
+}
+
+null_argument_e::~null_argument_e() noexcept
+{
+}
+
+out_of_mem_e::out_of_mem_e(const pstring &location)
+ : pexception(pfmt("Out of memory: {}")(location))
+{
+}
+
+out_of_mem_e::~out_of_mem_e() noexcept
+{
+}
+
+fpexception_e::fpexception_e(const pstring &text)
+ : pexception(pfmt("Out of memory: {}")(text))
+{
+}
+
+fpexception_e::~fpexception_e() noexcept
+{
+}
+
+bool fpsignalenabler::m_enable = false;
+
+fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
{
+ int b = 0;
+ if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
+ if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
+ if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
+ if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
+ if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
+ m_last_enabled = feenableexcept(b);
}
+#else
+ m_last_enabled = 0;
+#endif
+}
- null_argument_e::null_argument_e(const pstring &argument)
- : pexception(pfmt("Null argument passed: {}")(argument))
- {
- }
-
-
- out_of_mem_e::out_of_mem_e(const pstring &location)
- : pexception(pfmt("Out of memory: {}")(location))
- {
- }
-
-
- fpexception_e::fpexception_e(const pstring &text)
- : pexception(pfmt("Out of memory: {}")(text))
- {
- }
-
-
- bool fpsignalenabler::m_enable = false;
-
- fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
- {
- #if HAS_FEENABLE_EXCEPT
- if (m_enable)
- {
- int b = 0;
- if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
- if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
- if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
- if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
- if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
- m_last_enabled = feenableexcept(b);
- }
- #else
- m_last_enabled = 0;
- #endif
- }
-
-
- fpsignalenabler::~fpsignalenabler()
+fpsignalenabler::~fpsignalenabler()
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
{
- #if HAS_FEENABLE_EXCEPT
- if (m_enable)
- {
- fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
- feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
- }
- #endif
+ fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
+ feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
}
+#endif
+}
- bool fpsignalenabler::supported()
- {
- return true;
- }
+bool fpsignalenabler::supported()
+{
+ return true;
+}
- bool fpsignalenabler::global_enable(bool enable)
- {
- bool old = m_enable;
- m_enable = enable;
- return old;
- }
+bool fpsignalenabler::global_enable(bool enable)
+{
+ bool old = m_enable;
+ m_enable = enable;
+ return old;
+}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h
index 28a3ac1adf1..4827081b754 100644
--- a/src/lib/netlist/plib/pexception.h
+++ b/src/lib/netlist/plib/pexception.h
@@ -9,116 +9,118 @@
#define PEXCEPTION_H_
#include "pstring.h"
-#include "ptypes.h"
#include <exception>
namespace plib {
+//============================================================
+// exception base
+//============================================================
+
+class pexception : public std::exception
+{
+public:
+ explicit pexception(const pstring &text);
+ pexception(const pexception &e) : std::exception(e), m_text(e.m_text) { }
+
+ virtual ~pexception() noexcept;
+
+ const pstring &text() { return m_text; }
+ const char* what() const noexcept override { return m_text.c_str(); }
+
+private:
+ pstring m_text;
+};
+
+class file_e : public plib::pexception
+{
+public:
+ file_e(const pstring &fmt, const pstring &filename);
+ file_e(const file_e &e) : pexception(e) { }
+ virtual ~file_e() noexcept;
+};
+
+class file_open_e : public file_e
+{
+public:
+ explicit file_open_e(const pstring &filename);
+ file_open_e(const file_open_e &e) : file_e(e) { }
+ virtual ~file_open_e() noexcept;
+};
+
+class file_read_e : public file_e
+{
+public:
+ explicit file_read_e(const pstring &filename);
+ file_read_e(const file_read_e &e) : file_e(e) { }
+ virtual ~file_read_e() noexcept;
+};
+
+class file_write_e : public file_e
+{
+public:
+ explicit file_write_e(const pstring &filename);
+ file_write_e(const file_write_e &e) : file_e(e) { }
+ virtual ~file_write_e() noexcept;
+};
+
+class null_argument_e : public plib::pexception
+{
+public:
+ explicit null_argument_e(const pstring &argument);
+ null_argument_e(const null_argument_e &e) : pexception(e) { }
+ virtual ~null_argument_e() noexcept;
+};
+
+class out_of_mem_e : public plib::pexception
+{
+public:
+ explicit out_of_mem_e(const pstring &location);
+ out_of_mem_e(const out_of_mem_e &e) : pexception(e) { }
+ virtual ~out_of_mem_e() noexcept;
+};
+
+/* FIXME: currently only a stub for later use. More use could be added by
+ * using “-fnon-call-exceptions" and sigaction to enable c++ exception supported.
+ */
+
+class fpexception_e : public pexception
+{
+public:
+ explicit fpexception_e(const pstring &text);
+ fpexception_e(const fpexception_e &e) : pexception(e) { }
+ virtual ~fpexception_e() noexcept;
+};
+
+static constexpr unsigned FP_INEXACT = 0x0001;
+static constexpr unsigned FP_DIVBYZERO = 0x0002;
+static constexpr unsigned FP_UNDERFLOW = 0x0004;
+static constexpr unsigned FP_OVERFLOW = 0x0008;
+static constexpr unsigned FP_INVALID = 0x00010;
+static constexpr unsigned FP_ALL = 0x0001f;
+
+/*
+ * Catch SIGFPE on linux for debugging purposes.
+ */
+
+class fpsignalenabler
+{
+public:
+ explicit fpsignalenabler(unsigned fpexceptions);
+ ~fpsignalenabler();
+
+ /* is the functionality supported ? */
+ static bool supported();
+ /* returns last global enable state */
+ static bool global_enable(bool enable);
+
+private:
+ int m_last_enabled;
+
+ static bool m_enable;
+};
+
- //============================================================
- // terminate
- //============================================================
-
- /*! Terminate the program
- *
- * \note could be enhanced by setting a termination handler
- */
- [[noreturn]] void terminate(const pstring &msg) noexcept;
-
- //============================================================
- // exception base
- //============================================================
-
- class pexception : public std::exception
- {
- public:
- explicit pexception(const pstring &text);
-
- const pstring &text() { return m_text; }
- const char* what() const noexcept override { return m_text.c_str(); }
-
- private:
- pstring m_text;
- };
-
- class file_e : public plib::pexception
- {
- public:
- file_e(const pstring &fmt, const pstring &filename);
- };
-
- class file_open_e : public file_e
- {
- public:
- explicit file_open_e(const pstring &filename);
- };
-
- class file_read_e : public file_e
- {
- public:
- explicit file_read_e(const pstring &filename);
- };
-
- class file_write_e : public file_e
- {
- public:
- explicit file_write_e(const pstring &filename);
- };
-
- class null_argument_e : public plib::pexception
- {
- public:
- explicit null_argument_e(const pstring &argument);
- };
-
- class out_of_mem_e : public plib::pexception
- {
- public:
- explicit out_of_mem_e(const pstring &location);
- };
-
- /* FIXME: currently only a stub for later use. More use could be added by
- * using “-fnon-call-exceptions" and sigaction to enable c++ exception supported.
- */
-
- class fpexception_e : public pexception
- {
- public:
- explicit fpexception_e(const pstring &text);
- };
-
- static constexpr unsigned FP_INEXACT = 0x0001;
- static constexpr unsigned FP_DIVBYZERO = 0x0002;
- static constexpr unsigned FP_UNDERFLOW = 0x0004;
- static constexpr unsigned FP_OVERFLOW = 0x0008;
- static constexpr unsigned FP_INVALID = 0x00010;
- static constexpr unsigned FP_ALL = 0x0001f;
-
- /*
- * Catch SIGFPE on linux for debugging purposes.
- */
-
- class fpsignalenabler
- {
- public:
- explicit fpsignalenabler(unsigned fpexceptions);
-
- COPYASSIGNMOVE(fpsignalenabler, delete)
-
- ~fpsignalenabler();
-
- /* is the functionality supported ? */
- static bool supported();
- /* returns last global enable state */
- static bool global_enable(bool enable);
-
- private:
- int m_last_enabled;
-
- static bool m_enable;
- };
-
-
-} // namespace plib
+}
#endif /* PEXCEPTION_H_ */
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index af87251fbdf..b8b5fcb3b91 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -8,96 +8,83 @@
#include "pfmtlog.h"
#include "palloc.h"
-#include <algorithm>
-#include <array>
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
#include <cstring>
-#include <iostream>
+#include <cstdlib>
+#include <cstdarg>
+#include <algorithm>
#include <locale>
+#include <iostream>
namespace plib {
pfmt &pfmt::format_element(const char *l, const unsigned cfmt_spec, ...)
{
va_list ap;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
- std::array<char, 2048> buf;
+ va_start(ap, cfmt_spec);
+ pstring fmt("%");
+ char buf[2048]; // FIXME
std::size_t sl;
- bool found_abs = false;
m_arg++;
- do {
- pstring fmt("%");
- va_start(ap, cfmt_spec);
- found_abs = false;
- buf[0] = 0;
- pstring search("{");
- search += plib::to_string(m_arg);
- sl = search.size();
+ pstring search("{");
+ search += plib::to_string(m_arg);
+ sl = search.length();
- auto p = m_str.find(search + ":");
- sl++; // ":"
- if (p == pstring::npos) // no further specifiers
+ auto p = m_str.find(search + ":");
+ sl++; // ":"
+ if (p == pstring::npos) // no further specifiers
+ {
+ p = m_str.find(search + "}");
+ if (p == pstring::npos) // not found try default
{
- p = m_str.find(search + "}");
- if (p == pstring::npos) // not found try default
- {
- sl = 2;
- p = m_str.find("{}");
- }
- else
- // found absolute positional place holder
- found_abs = true;
- if (p == pstring::npos)
- {
- sl=2;
- p = m_str.find("{:");
- if (p != pstring:: npos)
- {
- auto p1 = m_str.find("}", p);
- if (p1 != pstring::npos)
- {
- sl = p1 - p + 1;
- fmt += m_str.substr(p+1, p1 - p - 1);
- }
- }
- }
+ sl = 2;
+ p = m_str.find("{}");
}
- else
+ if (p == pstring::npos)
{
- // found absolute positional place holder
- auto p1 = m_str.find("}", p);
- if (p1 != pstring::npos)
+ sl=1;
+ p = m_str.find("{");
+ if (p != pstring:: npos)
{
- sl = p1 - p + 1;
- fmt += ((m_arg>=10) ? m_str.substr(p+4, p1 - p - 4) : m_str.substr(p+3, p1 - p - 3));
- found_abs = true;
+ auto p1 = m_str.find("}", p);
+ if (p1 != pstring::npos)
+ {
+ sl = p1 - p + 1;
+ fmt += m_str.substr(p+1, p1 - p - 1);
+ }
}
}
- pstring::value_type pend = fmt.at(fmt.size() - 1);
- if (pstring("duxo").find(cfmt_spec) != pstring::npos)
+ }
+ else
+ {
+ auto p1 = m_str.find("}", p);
+ if (p1 != pstring::npos)
{
- if (pstring("duxo").find(pend) == pstring::npos)
- fmt += (pstring(l) + static_cast<pstring::value_type>(cfmt_spec));
- else
- fmt = plib::left(fmt, fmt.size() - 1) + pstring(l) + plib::right(fmt, 1);
- }
- else if (pstring("fge").find(cfmt_spec) != pstring::npos)
- {
- if (pstring("fge").find(pend) == pstring::npos)
- fmt += cfmt_spec;
+ sl = p1 - p + 1;
+ fmt += ((m_arg>=10) ? m_str.substr(p+4, p1 - p - 4) : m_str.substr(p+3, p1 - p - 3));
}
+ }
+ pstring::code_t pend = fmt.at(fmt.length() - 1);
+ if (pstring("duxo").find(cfmt_spec) != pstring::npos)
+ {
+ if (pstring("duxo").find(pend) == pstring::npos)
+ fmt += (pstring(l, pstring::UTF8) + cfmt_spec);
else
+ fmt = fmt.left(fmt.length() - 1) + pstring(l, pstring::UTF8) + fmt.right(1);
+ }
+ else if (pstring("fge").find(cfmt_spec) != pstring::npos)
+ {
+ if (pstring("fge").find(pend) == pstring::npos)
fmt += cfmt_spec;
- std::vsnprintf(buf.data(), buf.size(), fmt.c_str(), ap);
- if (p != pstring::npos)
- m_str = m_str.substr(0, p) + pstring(buf.data()) + m_str.substr(p + sl);
- va_end(ap);
- } while (found_abs);
+ }
+ else
+ fmt += cfmt_spec;
+ vsprintf(buf, fmt.c_str(), ap);
+ if (p != pstring::npos)
+ m_str = m_str.substr(0, p) + pstring(buf, pstring::UTF8) + m_str.substr(p + sl);
+ va_end(ap);
return *this;
}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index cb9b59c01ce..9b7a85d8d8d 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -9,7 +9,6 @@
#include "pstring.h"
#include "ptypes.h"
-#include "putil.h"
#include <limits>
@@ -35,6 +34,7 @@ struct ptype_traits_base
template <>
struct ptype_traits_base<bool>
{
+ static unsigned int cast(bool &x) { return static_cast<unsigned int>(x); }
static unsigned int cast(const bool &x) { return static_cast<unsigned int>(x); }
static const bool is_signed = std::numeric_limits<bool>::is_signed;
static const char *size_spec() { return ""; }
@@ -136,6 +136,7 @@ struct ptype_traits<double> : ptype_traits_base<double>
static char32_t fmt_spec() { return 'f'; }
};
+
template<>
struct ptype_traits<char *> : ptype_traits_base<char *>
{
@@ -143,13 +144,6 @@ struct ptype_traits<char *> : ptype_traits_base<char *>
static char32_t fmt_spec() { return 's'; }
};
-template<>
-struct ptype_traits<std::string> : ptype_traits_base<char *>
-{
- static const char *cast(const std::string &x) { return x.c_str(); }
- static char32_t fmt_spec() { return 's'; }
-};
-
class pfmt
{
public:
@@ -157,57 +151,44 @@ public:
: m_str(fmt), m_arg(0)
{
}
- COPYASSIGNMOVE(pfmt, default)
- ~pfmt() noexcept = default;
+ pfmt(const pfmt &rhs) : m_str(rhs.m_str), m_arg(rhs.m_arg) { }
+
+ ~pfmt()
+ {
+ }
operator pstring() const { return m_str; }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt & e(const double &x) {return format_element("", 'e', x); }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt & g(const double &x) {return format_element("", 'g', x); }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt & e(const float &x) {return format_element("", 'e', static_cast<double>(x)); }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt & g(const float &x) {return format_element("", 'g', static_cast<double>(x)); }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt &operator ()(const void *x) {return format_element("", 'p', x); }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
pfmt &operator ()(const pstring &x) {return format_element("", 's', x.c_str() ); }
template<typename T>
pfmt &operator ()(const T &x)
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
return format_element(ptype_traits<T>::size_spec(), ptype_traits<T>::fmt_spec(), ptype_traits<T>::cast(x));
}
template<typename T>
pfmt &operator ()(const T *x)
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
return format_element(ptype_traits<T *>::size_spec(), ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x));
}
- template<typename X, typename Y, typename... Args>
- pfmt &operator()(X&& x, Y && y, Args&&... args)
- {
- return ((*this)(std::forward<X>(x)))(std::forward<Y>(y), std::forward<Args>(args)...);
- }
-
template<typename T>
pfmt &x(const T &x)
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
return format_element(ptype_traits<T>::size_spec(), 'x', x);
}
template<typename T>
pfmt &o(const T &x)
{
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
return format_element(ptype_traits<T>::size_spec(), 'o', x);
}
@@ -222,13 +203,11 @@ private:
};
template <class T, bool build_enabled = true>
-class pfmt_writer_t
+class pfmt_writer_t : plib::nocopyassignmove
{
public:
explicit pfmt_writer_t() : m_enabled(true) { }
- COPYASSIGNMOVE(pfmt_writer_t, delete)
-
/* runtime enable */
template<bool enabled, typename... Args>
void log(const pstring & fmt, Args&&... args) const
@@ -258,7 +237,7 @@ public:
bool is_enabled() const { return m_enabled; }
protected:
- ~pfmt_writer_t() noexcept = default;
+ ~pfmt_writer_t() { }
private:
pfmt &xlog(pfmt &fmt) const { return fmt; }
@@ -279,10 +258,7 @@ class plog_channel : public pfmt_writer_t<plog_channel<T, L, build_enabled>, bui
friend class pfmt_writer_t<plog_channel<T, L, build_enabled>, build_enabled>;
public:
explicit plog_channel(T &b) : pfmt_writer_t<plog_channel, build_enabled>(), m_base(b) { }
-
- COPYASSIGNMOVE(plog_channel, delete)
-
- ~plog_channel() noexcept = default;
+ ~plog_channel() { }
protected:
void vdowrite(const pstring &ls) const
@@ -307,9 +283,7 @@ public:
error(proxy),
fatal(proxy)
{}
-
- COPYASSIGNMOVE(plog_base, default)
- virtual ~plog_base() noexcept = default;
+ virtual ~plog_base() {}
plog_channel<T, plog_level::DEBUG, debug_enabled> debug;
plog_channel<T, plog_level::INFO> info;
@@ -319,7 +293,7 @@ public:
plog_channel<T, plog_level::FATAL> fatal;
};
-} // namespace plib
+}
template<typename T>
plib::pfmt& operator<<(plib::pfmt &p, T&& val) { return p(std::forward<T>(val)); }
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 6a2179e0e6f..79f09cb4a46 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -6,9 +6,9 @@
*/
#include "pfunction.h"
-#include "pexception.h"
#include "pfmtlog.h"
#include "putil.h"
+#include "pexception.h"
#include <cmath>
#include <stack>
@@ -17,7 +17,7 @@ namespace plib {
void pfunction::compile(const std::vector<pstring> &inputs, const pstring &expr)
{
- if (plib::startsWith(expr, "rpn:"))
+ if (expr.startsWith("rpn:"))
compile_postfix(inputs, expr.substr(4));
else
compile_infix(inputs, expr);
@@ -56,7 +56,7 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
{ rc.m_cmd = RAND; stk += 1; }
else
{
- for (std::size_t i = 0; i < inputs.size(); i++)
+ for (unsigned i = 0; i < inputs.size(); i++)
{
if (inputs[i] == cmd)
{
@@ -68,9 +68,9 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
}
if (rc.m_cmd != PUSH_INPUT)
{
+ bool err = false;
rc.m_cmd = PUSH_CONST;
- bool err;
- rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
+ rc.m_param = cmd.as_double(&err);
if (err)
throw plib::pexception(plib::pfmt("nld_function: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
stk += 1;
@@ -84,11 +84,11 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
throw plib::pexception(plib::pfmt("nld_function: stack count different to one on <{2}>")(expr));
}
-static int get_prio(const pstring &v)
+static int get_prio(pstring v)
{
if (v == "(" || v == ")")
return 1;
- else if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
+ else if (v.left(1) >= "a" && v.left(1) <= "z")
return 0;
else if (v == "*" || v == "/")
return 20;
@@ -113,11 +113,12 @@ void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring
{
// Shunting-yard infix parsing
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
- std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, pstring(" "), pstring("")), sep));
+ std::vector<pstring> sexpr(plib::psplit(expr.replace_all(" ",""), sep));
std::stack<pstring> opstk;
std::vector<pstring> postfix;
- for (std::size_t i = 0; i < sexpr.size(); i++)
+ //printf("dbg: %s\n", expr.c_str());
+ for (unsigned i = 0; i < sexpr.size(); i++)
{
pstring &s = sexpr[i];
if (s=="(")
@@ -181,15 +182,14 @@ void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring
#define OP(OP, ADJ, EXPR) \
case OP: \
- ptr-= (ADJ); \
- stack[ptr-1] = (EXPR); \
+ ptr-=ADJ; \
+ stack[ptr-1] = EXPR; \
break;
double pfunction::evaluate(const std::vector<double> &values)
{
- std::array<double, 20> stack = { 0 };
+ double stack[20];
unsigned ptr = 0;
- stack[0] = 0.0;
for (auto &rc : m_precompiled)
{
switch (rc.m_cmd)
@@ -199,8 +199,8 @@ double pfunction::evaluate(const std::vector<double> &values)
OP(SUB, 1, ST2 - ST1)
OP(DIV, 1, ST2 / ST1)
OP(POW, 1, std::pow(ST2, ST1))
- OP(SIN, 0, std::sin(ST2))
- OP(COS, 0, std::cos(ST2))
+ OP(SIN, 0, std::sin(ST2));
+ OP(COS, 0, std::cos(ST2));
case RAND:
stack[ptr++] = lfsr_random();
break;
@@ -215,4 +215,4 @@ double pfunction::evaluate(const std::vector<double> &values)
return stack[ptr-1];
}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index fbb6c508333..7d5984f9d15 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -8,8 +8,8 @@
#ifndef PFUNCTION_H_
#define PFUNCTION_H_
-#include "pstate.h"
#include "pstring.h"
+#include "pstate.h"
#include <vector>
@@ -112,6 +112,6 @@ namespace plib {
};
-} // namespace plib
+}
#endif /* PEXCEPTION_H_ */
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index c2fee9c2f8e..5fefa658b83 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -12,8 +12,6 @@
#include "pstring.h"
-#include <array>
-#include <type_traits>
#include <vector>
namespace plib {
@@ -31,13 +29,14 @@ class uninitialised_array_t
{
public:
- using iterator = C *;
- using const_iterator = const C *;
+ typedef C* iterator;
+ typedef const C* const_iterator;
- uninitialised_array_t() noexcept = default;
+ uninitialised_array_t()
+ {
+ }
- COPYASSIGNMOVE(uninitialised_array_t, delete)
- ~uninitialised_array_t() noexcept
+ ~uninitialised_array_t()
{
for (std::size_t i=0; i<N; i++)
(*this)[i].~C();
@@ -52,7 +51,7 @@ public:
const C& operator[](const std::size_t &index) const noexcept
{
- return *reinterpret_cast<const C *>(&m_buf[index]);
+ return *reinterpret_cast<C *>(&m_buf[index]);
}
template<typename... Args>
@@ -76,8 +75,7 @@ protected:
private:
/* ensure proper alignment */
- PALIGNAS_VECTOROPT()
- std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
+ typename std::aligned_storage<sizeof(C), alignof(C)>::type m_buf[N];
};
// ----------------------------------------------------------------------------------------
@@ -85,7 +83,6 @@ private:
// the list allows insertions / deletions if used properly
// ----------------------------------------------------------------------------------------
-#if 0
template <class LC>
class linkedlist_t
{
@@ -155,10 +152,9 @@ public:
void remove(const LC *elem) noexcept
{
auto p = &m_head;
- while(*p != elem)
+ for ( ; *p != elem; p = &((*p)->m_next))
{
//nl_assert(*p != nullptr);
- p = &((*p)->m_next);
}
(*p) = elem->m_next;
}
@@ -170,105 +166,7 @@ public:
private:
LC *m_head;
};
-#else
-template <class LC>
-class linkedlist_t
-{
-public:
-
- struct element_t
- {
- public:
-
- friend class linkedlist_t<LC>;
-
- constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
- ~element_t() noexcept = default;
-
- COPYASSIGNMOVE(element_t, delete)
-
- constexpr LC *next() const noexcept { return m_next; }
- constexpr LC *prev() const noexcept { return m_prev; }
- private:
- LC * m_next;
- LC * m_prev;
- };
-
- struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
- {
- private:
- LC* p;
- public:
- explicit constexpr iter_t(LC* x) noexcept : p(x) { }
- constexpr iter_t(iter_t &rhs) noexcept : p(rhs.p) { }
- iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); }
- iter_t& operator=(const iter_t &rhs) noexcept { iter_t t(rhs); std::swap(*this, t); return *this; }
- iter_t& operator=(iter_t &&rhs) noexcept { std::swap(*this, rhs); return *this; }
- iter_t& operator++() noexcept {p = p->next();return *this;}
- // NOLINTNEXTLINE(cert-dcl21-cpp)
- iter_t operator++(int) & noexcept {const iter_t tmp(*this); operator++(); return tmp;}
-
- ~iter_t() = default;
-
- constexpr bool operator==(const iter_t& rhs) const noexcept {return p == rhs.p;}
- constexpr bool operator!=(const iter_t& rhs) const noexcept {return p != rhs.p;}
- /* constexpr */ LC& operator*() noexcept {return *p;}
- /* constexpr */ LC* operator->() noexcept {return p;}
-
- constexpr LC& operator*() const noexcept {return *p;}
- constexpr LC* operator->() const noexcept {return p;}
- };
-
- constexpr linkedlist_t() : m_head(nullptr) {}
- constexpr iter_t begin() const noexcept { return iter_t(m_head); }
- constexpr iter_t end() const noexcept { return iter_t(nullptr); }
-
- void push_front(LC *elem) noexcept
- {
- if (m_head)
- m_head->m_prev = elem;
- elem->m_next = m_head;
- elem->m_prev = nullptr;
- m_head = elem;
- }
-
- void push_back(LC *elem) noexcept
- {
- LC ** p(&m_head);
- LC * prev(nullptr);
- while (*p != nullptr)
- {
- prev = *p;
- p = &((*p)->m_next);
- }
- *p = elem;
- elem->m_prev = prev;
- elem->m_next = nullptr;
- }
-
- void remove(const LC *elem) noexcept
- {
- if (elem->m_prev)
- elem->m_prev->m_next = elem->m_next;
- else
- m_head = elem->m_next;
- if (elem->m_next)
- elem->m_next->m_prev = elem->m_prev;
- else
- {
- /* update tail */
- }
- }
-
- LC *front() const noexcept { return m_head; }
- void clear() noexcept { m_head = nullptr; }
- constexpr bool empty() const noexcept { return (m_head == nullptr); }
-
-private:
- LC *m_head;
-};
-#endif
-} // namespace plib
+}
#endif /* PLISTS_H_ */
diff --git a/src/lib/netlist/plib/pmain.cpp b/src/lib/netlist/plib/pmain.cpp
index b381d96dca7..93c4076bac2 100644
--- a/src/lib/netlist/plib/pmain.cpp
+++ b/src/lib/netlist/plib/pmain.cpp
@@ -23,7 +23,7 @@ namespace plib {
char *buf = new char[dst_char_count + 1];
WideCharToMultiByte(CP_UTF8, 0, w, wlen, buf, dst_char_count, nullptr, nullptr);
buf[dst_char_count] = 0;
- auto ret = pstring(buf);
+ auto ret = pstring(buf, pstring::UTF8);
delete [] buf;
return ret;
}
@@ -37,13 +37,18 @@ namespace plib {
: options()
, pout_strm()
, perr_strm()
- , pout(&pout_strm)
- , perr(&perr_strm)
+ , pout(pout_strm)
+ , perr(perr_strm)
{
}
- int app::main_utfX(int argc, char **argv)
+ app::~app()
+ {
+
+ }
+
+ int app::main_utfX(int argc, char *argv[])
{
auto r = this->parse(argc, argv);
int ret = 0;
diff --git a/src/lib/netlist/plib/pmain.h b/src/lib/netlist/plib/pmain.h
index 4f4be779251..e2f84b90de6 100644
--- a/src/lib/netlist/plib/pmain.h
+++ b/src/lib/netlist/plib/pmain.h
@@ -10,21 +10,20 @@
#ifndef PMAIN_H_
#define PMAIN_H_
-#include "palloc.h"
#include "poptions.h"
-#include "pstream.h"
#include "pstring.h"
#include "putil.h"
+#include "pstream.h"
-#include <cwchar>
#include <memory>
+#include <cwchar>
#ifdef _WIN32
#define PMAIN(appclass) \
extern "C" int wmain(int argc, wchar_t *argv[]) { return plib::app::mainrun<appclass, wchar_t>(argc, argv); }
#else
#define PMAIN(appclass) \
-int main(int argc, char **argv) { return plib::app::mainrun<appclass, char>(argc, argv); }
+int main(int argc, char *argv[]) { return plib::app::mainrun<appclass, char>(argc, argv); }
#endif
@@ -37,10 +36,7 @@ namespace plib {
{
public:
app();
-
- COPYASSIGNMOVE(app, delete)
-
- virtual ~app() = default;
+ virtual ~app();
virtual pstring usage() = 0;
virtual int execute() = 0;
@@ -52,21 +48,21 @@ namespace plib {
plib::putf8_fmt_writer perr;
template <class C, typename T>
- static int mainrun(int argc, T **argv)
+ static int mainrun(int argc, T *argv[])
{
- auto a = plib::make_unique<C>();
+ auto a = std::unique_ptr<C>(new C);
return a->main_utfX(argc, argv);
}
private:
- int main_utfX(int argc, char **argv);
+ int main_utfX(int argc, char *argv[]);
#ifdef _WIN32
int main_utfX(int argc, wchar_t *argv[]);
#endif
};
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pmatrix2d.h b/src/lib/netlist/plib/pmatrix2d.h
deleted file mode 100644
index eab533688d7..00000000000
--- a/src/lib/netlist/plib/pmatrix2d.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * pmatrix2d.h
- *
- * NxM regular matrix
- *
- */
-
-#ifndef PMATRIX2D_H_
-#define PMATRIX2D_H_
-
-#include "palloc.h"
-
-#include <algorithm>
-#include <cmath>
-#include <cstdlib>
-#include <type_traits>
-#include <vector>
-
-namespace plib
-{
-
-
- template<typename T, typename A = aligned_allocator<T>>
- class pmatrix2d
- {
- public:
- using value_type = T;
- using allocator_type = A;
-
- static constexpr const std::size_t align_size = align_traits<A>::align_size;
- static constexpr const std::size_t stride_size = align_traits<A>::stride_size;
- pmatrix2d()
- : m_N(0), m_M(0), m_stride(8), m_v()
- {
- }
-
- pmatrix2d(std::size_t N, std::size_t M)
- : m_N(N), m_M(M), m_v()
- {
- m_stride = ((M + stride_size-1) / stride_size) * stride_size;
- m_v.resize(N * m_stride);
- }
-
- void resize(std::size_t N, std::size_t M)
- {
- m_N = N;
- m_M = M;
- m_stride = ((M + stride_size-1) / stride_size) * stride_size;
- m_v.resize(N * m_stride);
- }
-
- C14CONSTEXPR T * operator[] (std::size_t row) noexcept
- {
- return assume_aligned_ptr<T, align_size>(&m_v[m_stride * row]);
- }
-
- constexpr const T * operator[] (std::size_t row) const noexcept
- {
- return assume_aligned_ptr<T, align_size>(&m_v[m_stride * row]);
- }
-
- T & operator()(std::size_t r, std::size_t c) noexcept
- {
- return (*this)[r][c];
- }
-
- const T & operator()(std::size_t r, std::size_t c) const noexcept
- {
- return (*this)[r][c];
- }
-
- private:
-
- std::size_t m_N;
- std::size_t m_M;
- std::size_t m_stride;
-
- std::vector<T, A> m_v;
- };
-
-} // namespace plib
-
-#endif /* MAT_CR_H_ */
diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h
deleted file mode 100644
index f55807c86dc..00000000000
--- a/src/lib/netlist/plib/pmempool.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * pmempool.h
- *
- */
-
-#ifndef PMEMPOOL_H_
-#define PMEMPOOL_H_
-
-#include "palloc.h"
-#include "pstream.h"
-#include "pstring.h"
-#include "ptypes.h"
-#include "putil.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <memory>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-namespace plib {
-
- //============================================================
- // Memory pool
- //============================================================
-
- class mempool
- {
- private:
- struct block
- {
- block(mempool *mp, std::size_t min_bytes)
- : m_num_alloc(0)
- , m_cur(0)
- , m_data(nullptr)
- , m_mempool(mp)
- {
- min_bytes = std::max(mp->m_min_alloc, min_bytes);
- m_free = min_bytes;
- std::size_t alloc_bytes = (min_bytes + mp->m_min_align - 1) & ~(mp->m_min_align - 1);
- m_data_allocated = static_cast<char *>(::operator new(alloc_bytes));
- void *r = m_data_allocated;
- std::align(mp->m_min_align, min_bytes, r, alloc_bytes);
- m_data = reinterpret_cast<char *>(r);
- }
- std::size_t m_num_alloc;
- std::size_t m_free;
- std::size_t m_cur;
- char *m_data;
- char *m_data_allocated;
- mempool *m_mempool;
- };
-
- struct info
- {
- info(block *b, std::size_t p) : m_block(b), m_pos(p) { }
- ~info() = default;
- COPYASSIGNMOVE(info, default)
-
- block * m_block;
- std::size_t m_pos;
- };
-
-
- block * new_block(std::size_t min_bytes)
- {
- auto *b = plib::pnew<block>(this, min_bytes);
- m_blocks.push_back(b);
- return b;
- }
-
-
- static std::unordered_map<void *, info> &sinfo()
- {
- static std::unordered_map<void *, info> spinfo;
- return spinfo;
- }
-
- size_t m_min_alloc;
- size_t m_min_align;
-
- std::vector<block *> m_blocks;
-
- public:
- static constexpr const bool is_stateless = false;
- template <class T, std::size_t ALIGN = alignof(T)>
- using allocator_type = arena_allocator<mempool, T, ALIGN>;
-
- mempool(size_t min_alloc = (1<<21), size_t min_align = 16)
- : m_min_alloc(min_alloc), m_min_align(min_align)
- {
- }
-
- COPYASSIGNMOVE(mempool, delete)
-
- ~mempool()
- {
-
- for (auto & b : m_blocks)
- {
- if (b->m_num_alloc != 0)
- {
- plib::perrlogger("Found {} info blocks\n", sinfo().size());
- plib::perrlogger("Found block with {} dangling allocations\n", b->m_num_alloc);
- }
- ::operator delete(b->m_data);
- }
- }
-
- void *allocate(size_t align, size_t size)
- {
- if (align < m_min_align)
- align = m_min_align;
-
- size_t rs = size + align;
- for (auto &b : m_blocks)
- {
- if (b->m_free > rs)
- {
- b->m_free -= rs;
- b->m_num_alloc++;
- auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
- auto capacity(rs);
- ret = std::align(align, size, ret, capacity);
- // FIXME: if (ret == nullptr)
- // printf("Oh no\n");
- sinfo().insert({ ret, info(b, b->m_cur)});
- rs -= (capacity - size);
- b->m_cur += rs;
-
- return ret;
- }
- }
- {
- block *b = new_block(rs);
- b->m_num_alloc = 1;
- b->m_free = m_min_alloc - rs;
- auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
- auto capacity(rs);
- ret = std::align(align, size, ret, capacity);
- // FIXME: if (ret == nullptr)
- // printf("Oh no\n");
- sinfo().insert({ ret, info(b, b->m_cur)});
- rs -= (capacity - size);
- b->m_cur += rs;
- return ret;
- }
- }
-
- static void deallocate(void *ptr)
- {
-
- auto it = sinfo().find(ptr);
- if (it == sinfo().end())
- plib::terminate("mempool::free - pointer not found\n");
- info i = it->second;
- block *b = i.m_block;
- if (b->m_num_alloc == 0)
- plib::terminate("mempool::free - double free was called\n");
- else
- {
- //b->m_free = m_min_alloc;
- //b->cur_ptr = b->data;
- }
- b->m_num_alloc--;
- //printf("Freeing in block %p %lu\n", b, b->m_num_alloc);
- sinfo().erase(it);
- }
-
- template <typename T>
- using owned_pool_ptr = plib::owned_ptr<T, arena_deleter<mempool, T>>;
-
- template<typename T, typename... Args>
- owned_pool_ptr<T> make_poolptr(Args&&... args)
- {
- auto *mem = this->allocate(alignof(T), sizeof(T));
- return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<mempool, T>(this));
- }
-
- };
-
-} // namespace plib
-
-#endif /* PMEMPOOL_H_ */
diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h
index f8a516df485..6559207f09d 100644
--- a/src/lib/netlist/plib/pomp.h
+++ b/src/lib/netlist/plib/pomp.h
@@ -11,8 +11,6 @@
#include "pconfig.h"
-#include <cstddef>
-
#if HAS_OPENMP
#include "omp.h"
#endif
@@ -20,39 +18,29 @@
namespace plib {
namespace omp {
-template <typename I, class T>
-void for_static(const I start, const I end, const T &what)
+template <class T>
+void for_static(const int start, const int end, const T &what)
{
#if HAS_OPENMP && USE_OPENMP
#pragma omp parallel
#endif
{
#if HAS_OPENMP && USE_OPENMP
- #pragma omp for //schedule(static)
+ #pragma omp for schedule(static)
#endif
- for (I i = start; i < end; i++)
+ for (int i = start; i < end; i++)
what(i);
}
}
-template <typename I, class T>
-void for_static_np(const I start, const I end, const T &what)
-{
- for (I i = start; i < end; i++)
- what(i);
-}
-
-
-inline void set_num_threads(const std::size_t threads)
+inline void set_num_threads(const int threads)
{
#if HAS_OPENMP && USE_OPENMP
omp_set_num_threads(threads);
-#else
- plib::unused_var(threads);
#endif
}
-inline std::size_t get_max_threads()
+inline int get_max_threads()
{
#if HAS_OPENMP && USE_OPENMP
return omp_get_max_threads();
@@ -66,7 +54,7 @@ inline std::size_t get_max_threads()
// pdynlib: dynamic loading of libraries ...
// ----------------------------------------------------------------------------------------
-} // namespace omp
-} // namespace plib
+}
+}
#endif /* PSTRING_H_ */
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp
index 4a3d32c4723..910660acb3d 100644
--- a/src/lib/netlist/plib/poptions.cpp
+++ b/src/lib/netlist/plib/poptions.cpp
@@ -6,39 +6,77 @@
*/
#include "poptions.h"
-#include "pexception.h"
-#include "ptypes.h"
namespace plib {
/***************************************************************************
Options
***************************************************************************/
- option_base::option_base(options &parent, const pstring &help)
+ option_base::option_base(options &parent, pstring help)
: m_help(help)
{
parent.register_option(this);
}
- option::option(options &parent, const pstring &ashort, const pstring &along, const pstring &help, bool has_argument)
+ option_base::~option_base()
+ {
+ }
+
+ option_group::~option_group()
+ {
+ }
+
+ option_example::~option_example()
+ {
+ }
+
+ option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument)
: option_base(parent, help), m_short(ashort), m_long(along),
m_has_argument(has_argument), m_specified(false)
{
}
+ option::~option()
+ {
+ }
+
int option_str::parse(const pstring &argument)
{
m_val = argument;
return 0;
}
+ int option_str_limit::parse(const pstring &argument)
+ {
+ if (plib::container::contains(m_limit, argument))
+ {
+ m_val = argument;
+ return 0;
+ }
+ else
+ return 1;
+ }
+
int option_bool::parse(const pstring &argument)
{
- unused_var(argument);
m_val = true;
return 0;
}
+ int option_double::parse(const pstring &argument)
+ {
+ bool err = false;
+ m_val = argument.as_double(&err);
+ return (err ? 1 : 0);
+ }
+
+ int option_long::parse(const pstring &argument)
+ {
+ bool err = false;
+ m_val = argument.as_long(&err);
+ return (err ? 1 : 0);
+ }
+
int option_vec::parse(const pstring &argument)
{
bool err = false;
@@ -47,88 +85,53 @@ namespace plib {
}
options::options()
- : m_other_args(nullptr)
{
}
- options::options(option **o)
- : m_other_args(nullptr)
+ options::options(option *o[])
{
int i=0;
while (o[i] != nullptr)
{
- register_option(o[i]);
+ m_opts.push_back(o[i]);
i++;
}
}
- void options::register_option(option_base *opt)
+ options::~options()
{
- m_opts.push_back(opt);
+ m_opts.clear();
}
- void options::check_consistency()
+ void options::register_option(option_base *opt)
{
- for (auto &opt : m_opts)
- {
- auto *o = dynamic_cast<option *>(opt);
- if (o != nullptr)
- {
- if (o->short_opt() == "" && o->long_opt() == "")
- {
- auto *ov = dynamic_cast<option_args *>(o);
- if (ov != nullptr)
- {
- if (m_other_args != nullptr)
- {
- throw pexception("other args can only be specified once!");
- }
- else
- {
- m_other_args = ov;
- }
- }
- else
- throw pexception("found option with neither short or long tag!" );
- }
- }
- }
+ m_opts.push_back(opt);
}
- int options::parse(int argc, char **argv)
+ int options::parse(int argc, char *argv[])
{
- check_consistency();
- m_app = pstring(argv[0]);
- bool seen_other_args = false;
+ m_app = pstring(argv[0], pstring::UTF8);
for (int i=1; i<argc; )
{
- pstring arg(argv[i]);
+ pstring arg(argv[i], pstring::UTF8);
option *opt = nullptr;
pstring opt_arg;
bool has_equal_arg = false;
- if (!seen_other_args && plib::startsWith(arg, "--"))
+ if (arg.startsWith("--"))
{
auto v = psplit(arg.substr(2),"=");
- if (v.size() && v[0] != pstring(""))
- {
- opt = getopt_long(v[0]);
- has_equal_arg = (v.size() > 1);
- if (has_equal_arg)
- {
- for (std::size_t j = 1; j < v.size() - 1; j++)
- opt_arg = opt_arg + v[j] + "=";
- opt_arg += v[v.size()-1];
- }
- }
- else
+ opt = getopt_long(v[0]);
+ has_equal_arg = (v.size() > 1);
+ if (has_equal_arg)
{
- opt = m_other_args;
- seen_other_args = true;
+ for (unsigned j = 1; j < v.size() - 1; j++)
+ opt_arg = opt_arg + v[j] + "=";
+ opt_arg += v[v.size()-1];
}
}
- else if (!seen_other_args && plib::startsWith(arg, "-"))
+ else if (arg.startsWith("-"))
{
std::size_t p = 1;
opt = getopt_short(arg.substr(p, 1));
@@ -141,11 +144,7 @@ namespace plib {
}
else
{
- seen_other_args = true;
- if (m_other_args == nullptr)
- return i;
- opt = m_other_args;
- i--; // we haven't had an option specifier;
+ return i;
}
if (opt == nullptr)
return i;
@@ -159,7 +158,7 @@ namespace plib {
else
{
i++; // FIXME: are there more arguments?
- if (opt->do_parse(pstring(argv[i])) != 0)
+ if (opt->do_parse(pstring(argv[i], pstring::UTF8)) != 0)
return i - 1;
}
}
@@ -174,7 +173,7 @@ namespace plib {
return argc;
}
- pstring options::split_paragraphs(const pstring &text, unsigned width, unsigned indent,
+ pstring options::split_paragraphs(pstring text, unsigned width, unsigned indent,
unsigned firstline_indent)
{
auto paragraphs = psplit(text,"\n");
@@ -182,13 +181,13 @@ namespace plib {
for (auto &p : paragraphs)
{
- pstring line = plib::rpad(pstring(""), pstring(" "), firstline_indent);
+ pstring line = pstring("").rpad(" ", firstline_indent);
for (auto &s : psplit(p, " "))
{
if (line.length() + s.length() > width)
{
ret += line + "\n";
- line = plib::rpad(pstring(""), pstring(" "), indent);
+ line = pstring("").rpad(" ", indent);
}
line += s + " ";
}
@@ -197,8 +196,8 @@ namespace plib {
return ret;
}
- pstring options::help(const pstring &description, const pstring &usage,
- unsigned width, unsigned indent) const
+ pstring options::help(pstring description, pstring usage,
+ unsigned width, unsigned indent)
{
pstring ret;
@@ -207,10 +206,6 @@ namespace plib {
for (auto & optbase : m_opts )
{
- // Skip anonymous inputs which are collected in option_args
- if (dynamic_cast<option_args *>(optbase) != nullptr)
- continue;
-
if (auto opt = dynamic_cast<option *>(optbase))
{
pstring line = "";
@@ -226,20 +221,20 @@ namespace plib {
if (opt->has_argument())
{
line += "=";
- auto *ol = dynamic_cast<option_str_limit_base *>(opt);
+ option_str_limit *ol = dynamic_cast<option_str_limit *>(opt);
if (ol)
{
for (auto &v : ol->limit())
{
line += v + "|";
}
- line = plib::left(line, line.length() - 1);
+ line = line.left(line.length() - 1);
}
else
line += "Value";
}
}
- line = plib::rpad(line, pstring(" "), indent - 2) + " ";
+ line = line.rpad(" ", indent - 2) + " ";
if (line.length() > indent)
{
//ret += "TestGroup abc\n def gef\nxyz\n\n" ;
@@ -255,7 +250,6 @@ namespace plib {
if (grp->help() != "") ret += split_paragraphs(grp->help(), width, 4, 4) + "\n";
}
}
- // FIXME: other help ...
pstring ex("");
for (auto & optbase : m_opts )
{
@@ -272,22 +266,22 @@ namespace plib {
return ret;
}
- option *options::getopt_short(const pstring &arg) const
+ option *options::getopt_short(pstring arg)
{
for (auto & optbase : m_opts)
{
auto opt = dynamic_cast<option *>(optbase);
- if (opt && arg != "" && opt->short_opt() == arg)
+ if (opt && opt->short_opt() == arg)
return opt;
}
return nullptr;
}
- option *options::getopt_long(const pstring &arg) const
+ option *options::getopt_long(pstring arg)
{
for (auto & optbase : m_opts)
{
auto opt = dynamic_cast<option *>(optbase);
- if (opt && arg !="" && opt->long_opt() == arg)
+ if (opt && opt->long_opt() == arg)
return opt;
}
return nullptr;
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h
index 086fe32fc8a..491ac0b4d91 100644
--- a/src/lib/netlist/plib/poptions.h
+++ b/src/lib/netlist/plib/poptions.h
@@ -10,8 +10,8 @@
#ifndef POPTIONS_H_
#define POPTIONS_H_
-#include "plists.h"
#include "pstring.h"
+#include "plists.h"
#include "putil.h"
namespace plib {
@@ -24,12 +24,10 @@ class options;
class option_base
{
public:
- option_base(options &parent, const pstring &help);
- virtual ~option_base() = default;
-
- COPYASSIGNMOVE(option_base, delete)
+ option_base(options &parent, pstring help);
+ virtual ~option_base();
- pstring help() const { return m_help; }
+ pstring help() { return m_help; }
private:
pstring m_help;
};
@@ -37,10 +35,11 @@ private:
class option_group : public option_base
{
public:
- option_group(options &parent, const pstring &group, const pstring &help)
+ option_group(options &parent, pstring group, pstring help)
: option_base(parent, help), m_group(group) { }
+ ~option_group();
- pstring group() const { return m_group; }
+ pstring group() { return m_group; }
private:
pstring m_group;
};
@@ -48,10 +47,11 @@ private:
class option_example : public option_base
{
public:
- option_example(options &parent, const pstring &group, const pstring &help)
+ option_example(options &parent, pstring group, pstring help)
: option_base(parent, help), m_example(group) { }
+ ~option_example();
- pstring example() const { return m_example; }
+ pstring example() { return m_example; }
private:
pstring m_example;
};
@@ -60,7 +60,8 @@ private:
class option : public option_base
{
public:
- option(options &parent, const pstring &ashort, const pstring &along, const pstring &help, bool has_argument);
+ option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument);
+ ~option();
/* no_argument options will be called with "" argument */
@@ -88,177 +89,131 @@ private:
class option_str : public option
{
public:
- option_str(options &parent, const pstring &ashort, const pstring &along, const pstring &defval, const pstring &help)
+ option_str(options &parent, pstring ashort, pstring along, pstring defval, pstring help)
: option(parent, ashort, along, help, true), m_val(defval)
{}
- pstring operator ()() const { return m_val; }
+ pstring operator ()() { return m_val; }
protected:
- int parse(const pstring &argument) override;
+ virtual int parse(const pstring &argument) override;
private:
pstring m_val;
};
-class option_str_limit_base : public option
+class option_str_limit : public option
{
public:
- option_str_limit_base(options &parent, const pstring &ashort, const pstring &along, std::vector<pstring> &&limit, const pstring &help)
- : option(parent, ashort, along, help, true)
- , m_limit(limit)
+ option_str_limit(options &parent, pstring ashort, pstring along, pstring defval, pstring limit, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval)
+ , m_limit(plib::psplit(limit, ":"))
{
}
- const std::vector<pstring> &limit() const { return m_limit; }
+
+ pstring operator ()() { return m_val; }
+ const std::vector<pstring> &limit() { return m_limit; }
protected:
+ virtual int parse(const pstring &argument) override;
private:
+ pstring m_val;
std::vector<pstring> m_limit;
};
-
-template <typename T>
-class option_str_limit : public option_str_limit_base
+class option_bool : public option
{
public:
- option_str_limit(options &parent, const pstring &ashort, const pstring &along, const T &defval, std::vector<pstring> &&limit, const pstring &help)
- : option_str_limit_base(parent, ashort, along, std::move(limit), help), m_val(defval)
- {
- }
-
- T operator ()() const { return m_val; }
+ option_bool(options &parent, pstring ashort, pstring along, pstring help)
+ : option(parent, ashort, along, help, false), m_val(false)
+ {}
- pstring as_string() const { return limit()[m_val]; }
+ bool operator ()() { return m_val; }
protected:
- int parse(const pstring &argument) override
- {
- auto raw = plib::container::indexof(limit(), argument);
-
- if (raw != plib::container::npos)
- {
- m_val = static_cast<T>(raw);
- return 0;
- }
- else
- return 1;
- }
+ virtual int parse(const pstring &argument) override;
private:
- T m_val;
+ bool m_val;
};
-class option_bool : public option
+class option_double : public option
{
public:
- option_bool(options &parent, const pstring &ashort, const pstring &along, const pstring &help)
- : option(parent, ashort, along, help, false), m_val(false)
+ option_double(options &parent, pstring ashort, pstring along, double defval, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval)
{}
- bool operator ()() const { return m_val; }
+ double operator ()() { return m_val; }
protected:
- int parse(const pstring &argument) override;
+ virtual int parse(const pstring &argument) override;
private:
- bool m_val;
+ double m_val;
};
-template <typename T>
-class option_num : public option
+class option_long : public option
{
public:
- option_num(options &parent, const pstring &ashort, const pstring &along, T defval,
- const pstring &help,
- T minval = std::numeric_limits<T>::min(),
- T maxval = std::numeric_limits<T>::max() )
- : option(parent, ashort, along, help, true)
- , m_val(defval)
- , m_min(minval)
- , m_max(maxval)
+ option_long(options &parent, pstring ashort, pstring along, long defval, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval)
{}
- T operator ()() const { return m_val; }
+ long operator ()() { return m_val; }
protected:
- int parse(const pstring &argument) override
- {
- bool err;
- m_val = pstonum_ne<T>(argument, err);
- return (err ? 1 : (m_val < m_min || m_val > m_max));
- }
+ virtual int parse(const pstring &argument) override;
private:
- T m_val;
- T m_min;
- T m_max;
+ long m_val;
};
class option_vec : public option
{
public:
- option_vec(options &parent, const pstring &ashort, const pstring &along, const pstring &help)
+ option_vec(options &parent, pstring ashort, pstring along, pstring help)
: option(parent, ashort, along, help, true)
{}
- const std::vector<pstring> &operator ()() const { return m_val; }
+ std::vector<pstring> operator ()() { return m_val; }
protected:
- int parse(const pstring &argument) override;
+ virtual int parse(const pstring &argument) override;
private:
std::vector<pstring> m_val;
};
-class option_args : public option_vec
-{
-public:
- option_args(options &parent, const pstring &help)
- : option_vec(parent, "", "", help)
- {}
-};
-
-class options : public nocopyassignmove
+class options
{
public:
options();
- explicit options(option **o);
+ explicit options(option *o[]);
+
+ ~options();
void register_option(option_base *opt);
- int parse(int argc, char **argv);
+ int parse(int argc, char *argv[]);
- pstring help(const pstring &description, const pstring &usage,
- unsigned width = 72, unsigned indent = 20) const;
+ pstring help(pstring description, pstring usage,
+ unsigned width = 72, unsigned indent = 20);
- pstring app() const { return m_app; }
+ pstring app() { return m_app; }
private:
- static pstring split_paragraphs(const pstring &text, unsigned width, unsigned indent,
+ static pstring split_paragraphs(pstring text, unsigned width, unsigned indent,
unsigned firstline_indent);
- void check_consistency();
-
- template <typename T>
- T *getopt_type() const
- {
- for (auto & optbase : m_opts )
- {
- if (auto opt = dynamic_cast<T *>(optbase))
- return opt;
- }
- return nullptr;
- }
-
- option *getopt_short(const pstring &arg) const;
- option *getopt_long(const pstring &arg) const;
+ option *getopt_short(pstring arg);
+ option *getopt_long(pstring arg);
std::vector<option_base *> m_opts;
pstring m_app;
- option_args * m_other_args;
};
-} // namespace plib
+}
#endif /* POPTIONS_H_ */
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 5e1a231da81..7547572192d 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -16,6 +16,16 @@ namespace plib {
// A simple tokenizer
// ----------------------------------------------------------------------------------------
+ptokenizer::ptokenizer(plib::putf8_reader &strm)
+: m_strm(strm), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"')
+{
+}
+
+ptokenizer::~ptokenizer()
+{
+}
+
+
pstring ptokenizer::currentline_str()
{
return m_cur_line;
@@ -24,7 +34,7 @@ pstring ptokenizer::currentline_str()
void ptokenizer::skipeol()
{
- pstring::value_type c = getc();
+ pstring::code_t c = getc();
while (c)
{
if (c == 10)
@@ -39,11 +49,11 @@ void ptokenizer::skipeol()
}
-pstring::value_type ptokenizer::getc()
+pstring::code_t ptokenizer::getc()
{
if (m_unget != 0)
{
- pstring::value_type c = m_unget;
+ pstring::code_t c = m_unget;
m_unget = 0;
return c;
}
@@ -56,11 +66,11 @@ pstring::value_type ptokenizer::getc()
return 0;
return '\n';
}
- pstring::value_type c = *(m_px++);
+ pstring::code_t c = *(m_px++);
return c;
}
-void ptokenizer::ungetc(pstring::value_type c)
+void ptokenizer::ungetc(pstring::code_t c)
{
m_unget = c;
}
@@ -112,7 +122,6 @@ pstring ptokenizer::get_identifier_or_number()
return tok.str();
}
-// FIXME: combine into template
double ptokenizer::get_number_double()
{
token_t tok = get_token();
@@ -120,8 +129,8 @@ double ptokenizer::get_number_double()
{
error(pfmt("Expected a number, got <{1}>")(tok.str()) );
}
- bool err;
- auto ret = plib::pstonum_ne<double>(tok.str(), err);
+ bool err = false;
+ double ret = tok.str().as_double(&err);
if (err)
error(pfmt("Expected a number, got <{1}>")(tok.str()) );
return ret;
@@ -134,8 +143,8 @@ long ptokenizer::get_number_long()
{
error(pfmt("Expected a long int, got <{1}>")(tok.str()) );
}
- bool err;
- auto ret = plib::pstonum_ne<long>(tok.str(), err);
+ bool err = false;
+ long ret = tok.str().as_long(&err);
if (err)
error(pfmt("Expected a long int, got <{1}>")(tok.str()) );
return ret;
@@ -173,7 +182,7 @@ ptokenizer::token_t ptokenizer::get_token()
ptokenizer::token_t ptokenizer::get_token_internal()
{
/* skip ws */
- pstring::value_type c = getc();
+ pstring::code_t c = getc();
while (m_whitespace.find(c) != pstring::npos)
{
c = getc();
@@ -263,31 +272,28 @@ void ptokenizer::error(const pstring &errs)
// A simple preprocessor
// ----------------------------------------------------------------------------------------
-ppreprocessor::ppreprocessor(defines_map_type *defines)
-: pistream()
-, m_ifflag(0)
-, m_level(0)
-, m_lineno(0)
-, m_pos(0)
-, m_state(PROCESS)
-, m_comment(false)
+ppreprocessor::ppreprocessor(std::vector<define_t> *defines)
+: m_ifflag(0), m_level(0), m_lineno(0)
{
- m_expr_sep.emplace_back("!");
- m_expr_sep.emplace_back("(");
- m_expr_sep.emplace_back(")");
- m_expr_sep.emplace_back("+");
- m_expr_sep.emplace_back("-");
- m_expr_sep.emplace_back("*");
- m_expr_sep.emplace_back("/");
- m_expr_sep.emplace_back("&&");
- m_expr_sep.emplace_back("||");
- m_expr_sep.emplace_back("==");
- m_expr_sep.emplace_back(" ");
- m_expr_sep.emplace_back("\t");
+ m_expr_sep.push_back("!");
+ m_expr_sep.push_back("(");
+ m_expr_sep.push_back(")");
+ m_expr_sep.push_back("+");
+ m_expr_sep.push_back("-");
+ m_expr_sep.push_back("*");
+ m_expr_sep.push_back("/");
+ m_expr_sep.push_back("==");
+ m_expr_sep.push_back(" ");
+ m_expr_sep.push_back("\t");
- if (defines != nullptr)
- m_defines = *defines;
m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")});
+ if (defines != nullptr)
+ {
+ for (auto & p : *defines)
+ {
+ m_defines.insert({p.m_name, p});
+ }
+ }
}
void ppreprocessor::error(const pstring &err)
@@ -295,42 +301,35 @@ void ppreprocessor::error(const pstring &err)
throw pexception("PREPRO ERROR: " + err);
}
-pstream::size_type ppreprocessor::vread(value_type *buf, const pstream::size_type n)
-{
- size_type bytes = std::min(m_buf.size() - m_pos, n);
-
- if (bytes==0)
- return 0;
-
- std::memcpy(buf, m_buf.c_str() + m_pos, bytes);
- m_pos += bytes;
- return bytes;
-}
-
-#define CHECKTOK2(p_op, p_prio) \
- else if (tok == # p_op) \
- { \
- if (prio < (p_prio)) \
- return val; \
- start++; \
- const auto v2 = expr(sexpr, start, (p_prio)); \
- val = (val p_op v2); \
- } \
-// Operator precedence see https://en.cppreference.com/w/cpp/language/operator_precedence
-int ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio)
+double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio)
{
- int val = 0;
+ double val;
pstring tok=sexpr[start];
if (tok == "(")
{
start++;
- val = expr(sexpr, start, /*prio*/ 255);
+ val = expr(sexpr, start, /*prio*/ 0);
if (sexpr[start] != ")")
error("parsing error!");
start++;
}
+ else if (tok == "!")
+ {
+ start++;
+ val = expr(sexpr, start, 90);
+ if (val != 0)
+ val = 0;
+ else
+ val = 1;
+ }
+ else
+ {
+ tok=sexpr[start];
+ val = tok.as_double();
+ start++;
+ }
while (start < sexpr.size())
{
tok=sexpr[start];
@@ -339,25 +338,36 @@ int ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, i
// FIXME: catch error
return val;
}
- else if (tok == "!")
+ else if (tok == "+")
{
- if (prio < 3)
+ if (prio > 10)
return val;
start++;
- val = !expr(sexpr, start, 3);
+ val = val + expr(sexpr, start, 10);
}
- CHECKTOK2(*, 5)
- CHECKTOK2(/, 5)
- CHECKTOK2(+, 6)
- CHECKTOK2(-, 6)
- CHECKTOK2(==, 10)
- CHECKTOK2(&&, 14)
- CHECKTOK2(||, 15)
- else
+ else if (tok == "-")
{
- // FIXME: error handling
- val = plib::pstonum<decltype(val)>(tok);
+ if (prio > 10)
+ return val;
+ start++;
+ val = val - expr(sexpr, start, 10);
+ }
+ else if (tok == "*")
+ {
+ start++;
+ val = val * expr(sexpr, start, 20);
+ }
+ else if (tok == "/")
+ {
+ start++;
+ val = val / expr(sexpr, start, 20);
+ }
+ else if (tok == "==")
+ {
+ if (prio > 5)
+ return val;
start++;
+ val = (val == expr(sexpr, start, 5)) ? 1.0 : 0.0;
}
}
return val;
@@ -366,7 +376,10 @@ int ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, i
ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
{
auto idx = m_defines.find(name);
- return (idx != m_defines.end()) ? &idx->second : nullptr;
+ if (idx != m_defines.end())
+ return &idx->second;
+ else
+ return nullptr;
}
pstring ppreprocessor::replace_macros(const pstring &line)
@@ -376,135 +389,78 @@ pstring ppreprocessor::replace_macros(const pstring &line)
for (auto & elem : elems)
{
define_t *def = get_define(elem);
- ret += (def != nullptr) ? def->m_replace : elem;
+ if (def != nullptr)
+ ret += def->m_replace;
+ else
+ ret += elem;
}
return ret;
}
-static pstring catremainder(const std::vector<pstring> &elems, std::size_t start, const pstring &sep)
+static pstring catremainder(const std::vector<pstring> &elems, std::size_t start, pstring sep)
{
pstring ret("");
- for (std::size_t i = start; i < elems.size(); i++)
+ for (auto & elem : elems)
{
- ret += elems[i];
+ ret += elem;
ret += sep;
}
return ret;
}
-pstring ppreprocessor::process_comments(pstring line)
-{
- bool in_string = false;
-
- std::size_t e = line.size();
- pstring ret = "";
- for (std::size_t i=0; i < e; )
- {
- pstring c = plib::left(line, 1);
- line = line.substr(1);
- if (!m_comment)
- {
- if (c=="\"")
- {
- in_string = !in_string;
- ret += c;
- }
- else if (in_string && c=="\\")
- {
- i++;
- ret += (c + plib::left(line, 1));
- line = line.substr(1);
- }
- else if (!in_string && c=="/" && plib::left(line,1) == "*")
- m_comment = true;
- else if (!in_string && c=="/" && plib::left(line,1) == "/")
- break;
- else
- ret += c;
- }
- else
- if (c=="*" && plib::left(line,1) == "/")
- {
- i++;
- line = line.substr(1);
- m_comment = false;
- }
- i++;
- }
- return ret;
-}
-
-pstring ppreprocessor::process_line(pstring line)
+pstring ppreprocessor::process_line(const pstring &line)
{
- bool line_cont = plib::right(line, 1) == "\\";
- if (line_cont)
- line = plib::left(line, line.size() - 1);
-
- if (m_state == LINE_CONTINUATION)
- m_line += line;
- else
- m_line = line;
-
- if (line_cont)
- {
- m_state = LINE_CONTINUATION;
- return "";
- }
- else
- m_state = PROCESS;
-
- line = process_comments(m_line);
-
- pstring lt = plib::trim(plib::replace_all(line, pstring("\t"), pstring(" ")));
+ pstring lt = line.replace_all("\t"," ").trim();
pstring ret;
+ m_lineno++;
// FIXME ... revise and extend macro handling
- if (plib::startsWith(lt, "#"))
+ if (lt.startsWith("#"))
{
std::vector<pstring> lti(psplit(lt, " ", true));
- if (lti[0] == "#if")
+ if (lti[0].equals("#if"))
{
m_level++;
std::size_t start = 0;
lt = replace_macros(lt);
- std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep));
- auto val = static_cast<int>(expr(t, start, 255));
+ std::vector<pstring> t(psplit(lt.substr(3).replace_all(" ",""), m_expr_sep));
+ int val = static_cast<int>(expr(t, start, 0));
if (val == 0)
m_ifflag |= (1 << m_level);
}
- else if (lti[0] == "#ifdef")
+ else if (lti[0].equals("#ifdef"))
{
m_level++;
if (get_define(lti[1]) == nullptr)
m_ifflag |= (1 << m_level);
}
- else if (lti[0] == "#ifndef")
+ else if (lti[0].equals("#ifndef"))
{
m_level++;
if (get_define(lti[1]) != nullptr)
m_ifflag |= (1 << m_level);
}
- else if (lti[0] == "#else")
+ else if (lti[0].equals("#else"))
{
m_ifflag ^= (1 << m_level);
}
- else if (lti[0] == "#endif")
+ else if (lti[0].equals("#endif"))
{
m_ifflag &= ~(1 << m_level);
m_level--;
}
- else if (lti[0] == "#include")
+ else if (lti[0].equals("#include"))
{
// ignore
}
- else if (lti[0] == "#pragma")
+ else if (lti[0].equals("#pragma"))
{
- if (m_ifflag == 0 && lti.size() > 3 && lti[1] == "NETLIST")
+ if (m_ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST"))
{
- if (lti[2] == "warning")
+ if (lti[2].equals("warning"))
error("NETLIST: " + catremainder(lti, 3, " "));
}
}
- else if (lti[0] == "#define")
+ else if (lti[0].equals("#define"))
{
if (m_ifflag == 0)
{
@@ -514,20 +470,28 @@ pstring ppreprocessor::process_line(pstring line)
}
}
else
- {
- if (m_ifflag == 0)
- error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line)));
- }
+ error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line));
}
else
{
lt = replace_macros(lt);
if (m_ifflag == 0)
+ {
ret += lt;
+ }
}
return ret;
}
+void ppreprocessor::process(putf8_reader &istrm, putf8_writer &ostrm)
+{
+ pstring line;
+ while (istrm.readline(line))
+ {
+ line = process_line(line);
+ ostrm.writeline(line);
+ }
+}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h
index 1eca20e99ad..7ec517255c8 100644
--- a/src/lib/netlist/plib/pparser.h
+++ b/src/lib/netlist/plib/pparser.h
@@ -8,27 +8,20 @@
#ifndef PPARSER_H_
#define PPARSER_H_
+#include "pstring.h"
#include "plists.h"
#include "pstream.h"
-#include "pstring.h"
-#include <cstdint>
#include <unordered_map>
-
+#include <cstdint>
namespace plib {
-class ptokenizer
+class ptokenizer : nocopyassignmove
{
public:
- template <typename T>
- ptokenizer(T &&strm) // NOLINT(misc-forwarding-reference-overload, bugprone-forwarding-reference-overload)
- : m_strm(std::forward<T>(strm)), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"')
- {
- }
-
- COPYASSIGNMOVE(ptokenizer, delete)
+ explicit ptokenizer(plib::putf8_reader &strm);
- virtual ~ptokenizer() = default;
+ virtual ~ptokenizer();
enum token_type
{
@@ -98,23 +91,22 @@ public:
void require_token(const token_id_t &token_num);
void require_token(const token_t &tok, const token_id_t &token_num);
- token_id_t register_token(const pstring &token)
+ token_id_t register_token(pstring token)
{
token_id_t ret(m_tokens.size());
m_tokens.emplace(token, ret);
return ret;
}
- ptokenizer & identifier_chars(pstring s) { m_identifier_chars = std::move(s); return *this; }
- ptokenizer & number_chars(pstring st, pstring rem) { m_number_chars_start = std::move(st); m_number_chars = std::move(rem); return *this; }
- ptokenizer & string_char(pstring::value_type c) { m_string = c; return *this; }
- ptokenizer & whitespace(pstring s) { m_whitespace = std::move(s); return *this; }
- ptokenizer & comment(const pstring &start, const pstring &end, const pstring &line)
+ 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(pstring::code_t c) { m_string = c; }
+ void set_whitespace(pstring s) { m_whitespace = s; }
+ void set_comment(pstring start, pstring end, pstring line)
{
m_tok_comment_start = register_token(start);
m_tok_comment_end = register_token(end);
m_tok_line_comment = register_token(line);
- return *this;
}
token_t get_token_internal();
@@ -126,17 +118,17 @@ protected:
private:
void skipeol();
- pstring::value_type getc();
- void ungetc(pstring::value_type c);
+ pstring::code_t getc();
+ void ungetc(pstring::code_t c);
bool eof() { return m_strm.eof(); }
- putf8_reader m_strm;
+ putf8_reader &m_strm;
int m_lineno;
pstring m_cur_line;
pstring::const_iterator m_px;
- pstring::value_type m_unget;
+ pstring::code_t m_unget;
/* tokenizer stuff follows ... */
@@ -145,7 +137,7 @@ private:
pstring m_number_chars_start;
std::unordered_map<pstring, token_id_t> m_tokens;
pstring m_whitespace;
- pstring::value_type m_string;
+ pstring::code_t m_string;
token_id_t m_tok_comment_start;
token_id_t m_tok_comment_end;
@@ -153,7 +145,7 @@ private:
};
-class ppreprocessor : public pistream
+class ppreprocessor : plib::nocopyassignmove
{
public:
@@ -166,80 +158,29 @@ public:
pstring m_replace;
};
- using defines_map_type = std::unordered_map<pstring, define_t>;
-
- explicit ppreprocessor(defines_map_type *defines = nullptr);
- ~ppreprocessor() override = default;
-
- template <typename T>
- ppreprocessor & process(T &&istrm)
- {
- putf8_reader reader(std::forward<T>(istrm));
- pstring line;
- while (reader.readline(line))
- {
- m_lineno++;
- line = process_line(line);
- m_buf += decltype(m_buf)(line.c_str()) + static_cast<char>(10);
- }
- return *this;
- }
-
- COPYASSIGN(ppreprocessor, delete)
- ppreprocessor &operator=(ppreprocessor &&src) = delete;
+ explicit ppreprocessor(std::vector<define_t> *defines = nullptr);
+ virtual ~ppreprocessor() {}
-
- ppreprocessor(ppreprocessor &&s) noexcept
- : m_defines(std::move(s.m_defines))
- , m_expr_sep(std::move(s.m_expr_sep))
- , m_ifflag(s.m_ifflag)
- , m_level(s.m_level)
- , m_lineno(s.m_lineno)
- , m_buf(std::move(s.m_buf))
- , m_pos(s.m_pos)
- , m_state(s.m_state)
- , m_comment(s.m_comment)
- {
- }
+ void process(putf8_reader &istrm, putf8_writer &ostrm);
protected:
-
- size_type vread(value_type *buf, const size_type n) override;
- void vseek(const pos_type n) override
- {
- plib::unused_var(n);
- /* FIXME throw exception - should be done in base unless implemented */
- }
- pos_type vtell() const override { return m_pos; }
-
- int expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio);
+ double expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio);
define_t *get_define(const pstring &name);
pstring replace_macros(const pstring &line);
virtual void error(const pstring &err);
private:
- enum state_e
- {
- PROCESS,
- LINE_CONTINUATION
- };
- pstring process_line(pstring line);
- pstring process_comments(pstring line);
+ pstring process_line(const pstring &line);
- defines_map_type m_defines;
+ std::unordered_map<pstring, define_t> m_defines;
std::vector<pstring> m_expr_sep;
std::uint_least64_t m_ifflag; // 31 if levels
int m_level;
int m_lineno;
- pstring_t<pu8_traits> m_buf;
- pos_type m_pos;
- state_e m_state;
- pstring m_line;
- bool m_comment;
};
-} // namespace plib
+}
#endif /* PPARSER_H_ */
diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h
index 9c5329cccde..dc151d5d6a6 100644
--- a/src/lib/netlist/plib/ppmf.h
+++ b/src/lib/netlist/plib/ppmf.h
@@ -10,8 +10,9 @@
#include "pconfig.h"
-#include <cstdint>
#include <utility>
+#include <cstdint>
+
/*
*
@@ -69,8 +70,7 @@ namespace plib {
using generic_function = void (*)();
template<typename MemberFunctionType>
- mfp(MemberFunctionType mftp) // NOLINT(cppcoreguidelines-pro-type-member-init)
-
+ mfp(MemberFunctionType mftp)
: m_function(0), m_this_delta(0), m_size(sizeof(mfp))
{
*reinterpret_cast<MemberFunctionType *>(this) = mftp;
@@ -82,7 +82,7 @@ namespace plib {
mfp mfpo(mftp);
//return mfpo.update_after_bind<FunctionType>(object);
generic_function rfunc(nullptr);
- auto robject = reinterpret_cast<generic_class *>(object);
+ generic_class *robject = reinterpret_cast<generic_class *>(object);
mfpo.convert_to_generic(rfunc, robject);
func = reinterpret_cast<FunctionType>(rfunc);
object = reinterpret_cast<ObjectType *>(robject);
@@ -95,8 +95,7 @@ namespace plib {
if (PHAS_PMF_INTERNAL == 1)
{
// apply the "this" delta to the object first
- // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
- auto o_p_delta = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
+ generic_class * o_p_delta = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
// if the low bit of the vtable index is clear, then it is just a raw function pointer
if (!(m_function & 1))
@@ -242,28 +241,23 @@ namespace plib {
{
public:
class generic_class;
-
- template <class C>
- using MemberFunctionType = R (C::*)(Targs...);
-
pmfp() : pmfp_base<R, Targs...>(), m_obj(nullptr) {}
- template<typename O>
- pmfp(MemberFunctionType<O> mftp, O *object)
+ template<typename MemberFunctionType, typename O>
+ pmfp(MemberFunctionType mftp, O *object)
: pmfp_base<R, Targs...>()
{
this->set(mftp, object);
}
-
- template<typename O>
- void set(MemberFunctionType<O> mftp, O *object)
+ template<typename MemberFunctionType, typename O>
+ void set(MemberFunctionType mftp, O *object)
{
this->set_base(mftp, object);
m_obj = reinterpret_cast<generic_class *>(object);
}
- inline R operator()(Targs ... args)
+ inline R operator()(Targs... args)
{
return this->call(m_obj, std::forward<Targs>(args)...);
}
@@ -275,6 +269,6 @@ namespace plib {
};
-} // namespace plib
+}
#endif /* PPMF_H_ */
diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp
index 3bd93ed4f8e..043033ed1ea 100644
--- a/src/lib/netlist/plib/pstate.cpp
+++ b/src/lib/netlist/plib/pstate.cpp
@@ -9,6 +9,17 @@
#include "palloc.h"
namespace plib {
+state_manager_t::state_manager_t()
+{
+}
+
+state_manager_t::~state_manager_t()
+{
+ m_save.clear();
+ m_custom.clear();
+}
+
+
void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr)
{
@@ -18,40 +29,46 @@ void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, c
void state_manager_t::remove_save_items(const void *owner)
{
- auto i = m_save.end();
- while (i != m_save.begin())
+ for (auto i = m_save.begin(); i != m_save.end(); )
{
- i--;
if (i->get()->m_owner == owner)
i = m_save.erase(i);
+ else
+ i++;
}
- i = m_custom.end();
- while (i > m_custom.begin())
+ for (auto i = m_custom.begin(); i != m_custom.end(); )
{
- i--;
if (i->get()->m_owner == owner)
i = m_custom.erase(i);
+ else
+ i++;
}
}
void state_manager_t::pre_save()
{
for (auto & s : m_custom)
- s->m_callback->on_pre_save(*this);
+ s->m_callback->on_pre_save();
}
void state_manager_t::post_load()
{
for (auto & s : m_custom)
- s->m_callback->on_post_load(*this);
+ s->m_callback->on_post_load();
}
template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname)
{
+ //save_state_ptr(stname, DT_CUSTOM, 0, 1, &state);
callback_t *state_p = &state;
auto p = plib::make_unique<entry_t>(stname, owner, state_p);
m_custom.push_back(std::move(p));
state.register_state(*this, stname);
}
-} // namespace plib
+state_manager_t::callback_t::~callback_t()
+{
+}
+
+
+}
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index ac75ca6b69e..9757d6408b7 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -8,13 +8,11 @@
#ifndef PSTATE_H_
#define PSTATE_H_
-#include "palloc.h"
#include "pstring.h"
#include "ptypes.h"
-#include <array>
-#include <memory>
#include <vector>
+#include <memory>
// ----------------------------------------------------------------------------------------
// state saving ...
@@ -40,31 +38,32 @@ public:
const bool is_custom;
};
- template<typename T>
- static datatype_t dtype()
+ template<typename T> struct datatype_f
{
- return datatype_t(sizeof(T),
- plib::is_integral<T>::value || std::is_enum<T>::value,
- std::is_floating_point<T>::value);
- }
+ static inline const datatype_t f()
+ {
+ return datatype_t(sizeof(T),
+ plib::is_integral<T>::value || std::is_enum<T>::value,
+ std::is_floating_point<T>::value);
+ }
+ };
class callback_t
{
public:
using list_t = std::vector<callback_t *>;
+ virtual ~callback_t();
+
virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
- virtual void on_pre_save(state_manager_t &manager) = 0;
- virtual void on_post_load(state_manager_t &manager) = 0;
+ virtual void on_pre_save() = 0;
+ virtual void on_post_load() = 0;
protected:
- callback_t() = default;
- ~callback_t() = default;
- COPYASSIGNMOVE(callback_t, default)
};
struct entry_t
{
- using list_t = std::vector<plib::unique_ptr<entry_t>>;
+ using list_t = std::vector<std::unique_ptr<entry_t>>;
entry_t(const pstring &stname, const datatype_t &dt, const void *owner,
const std::size_t count, void *ptr)
@@ -73,6 +72,8 @@ public:
entry_t(const pstring &stname, const void *owner, callback_t *callback)
: m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }
+ ~entry_t() { }
+
pstring m_name;
const datatype_t m_dt;
const void * m_owner;
@@ -81,49 +82,35 @@ public:
void * m_ptr;
};
- state_manager_t() = default;
+ state_manager_t();
+ ~state_manager_t();
- template<typename C>
- void save_item(const void *owner, C &state, const pstring &stname)
+ template<typename C> void save_item(const void *owner, C &state, const pstring &stname)
{
- save_state_ptr( owner, stname, dtype<C>(), 1, &state);
+ save_state_ptr( owner, stname, datatype_f<C>::f(), 1, &state);
}
- template<typename C, std::size_t N>
- void save_item(const void *owner, C (&state)[N], const pstring &stname) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ template<typename C, std::size_t N> void save_item(const void *owner, C (&state)[N], const pstring &stname)
{
- save_state_ptr(owner, stname, dtype<C>(), N, &(state[0]));
+ 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 std::size_t 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, dtype<C>(), count, state);
+ save_state_ptr(owner, stname, datatype_f<C>::f(), count, state);
}
template<typename C>
void save_item(const void *owner, std::vector<C> &v, const pstring &stname)
{
- save_state_ptr(owner, stname, dtype<C>(), v.size(), v.data());
- }
-
- template<typename C, std::size_t N>
- void save_item(const void *owner, std::array<C, N> &a, const pstring &stname)
- {
- save_state_ptr(owner, stname, dtype<C>(), N, a.data());
+ save_state(v.data(), owner, stname, v.size());
}
void pre_save();
void post_load();
void remove_save_items(const void *owner);
- const std::vector<const entry_t *> save_list() const
- {
- std::vector<const entry_t *> ret;
- for (auto &i : m_save)
- ret.push_back(i.get());
- return ret;
- }
+ 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 std::size_t count, void *ptr);
@@ -137,6 +124,6 @@ private:
template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname);
-} // namespace plib
+}
#endif /* PSTATE_H_ */
diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp
index a7acdaafb52..420f63c9e5e 100644
--- a/src/lib/netlist/plib/pstream.cpp
+++ b/src/lib/netlist/plib/pstream.cpp
@@ -8,9 +8,9 @@
#include "pstream.h"
#include "palloc.h"
-#include <algorithm>
#include <cstdio>
#include <cstdlib>
+#include <algorithm>
// VS2015 prefers _dup
#ifdef _WIN32
@@ -21,14 +21,34 @@
namespace plib {
+pstream::~pstream()
+{
+}
+
// -----------------------------------------------------------------------------
// pistream: input stream
// -----------------------------------------------------------------------------
+pistream::~pistream()
+{
+}
+
// -----------------------------------------------------------------------------
// postream: output stream
// -----------------------------------------------------------------------------
+postream::~postream()
+{
+}
+
+void postream::write(pistream &strm)
+{
+ char buf[1024];
+ pos_type r;
+ while ((r=strm.read(buf, 1024)) > 0)
+ write(buf, r);
+}
+
// -----------------------------------------------------------------------------
// Input file stream
// -----------------------------------------------------------------------------
@@ -71,7 +91,7 @@ pifilestream::~pifilestream()
}
}
-pifilestream::pos_type pifilestream::vread(value_type *buf, const pos_type n)
+pifilestream::pos_type pifilestream::vread(void *buf, const pos_type n)
{
pos_type r = fread(buf, 1, n, static_cast<FILE *>(m_file));
if (r < n)
@@ -99,7 +119,7 @@ void pifilestream::vseek(const pos_type n)
throw file_e("Generic file operation failed: {}", m_filename);
}
-pifilestream::pos_type pifilestream::vtell() const
+pifilestream::pos_type pifilestream::vtell()
{
long ret = ftell(static_cast<FILE *>(m_file));
if (ret < 0)
@@ -120,6 +140,10 @@ pstdin::pstdin()
/* nothing to do */
}
+pstdin::~pstdin()
+{
+}
+
// -----------------------------------------------------------------------------
// Output file stream
// -----------------------------------------------------------------------------
@@ -156,11 +180,12 @@ pofilestream::~pofilestream()
}
}
-void pofilestream::vwrite(const value_type *buf, const pos_type n)
+void pofilestream::vwrite(const void *buf, const pos_type n)
{
std::size_t r = fwrite(buf, 1, n, static_cast<FILE *>(m_file));
if (r < n)
{
+ //printf("%ld %ld %s\n", r, n, strerror(errno));
if (ferror(static_cast<FILE *>(m_file)))
throw file_write_e(m_filename);
}
@@ -179,7 +204,7 @@ void pofilestream::vseek(const pos_type n)
}
}
-pstream::pos_type pofilestream::vtell() const
+pstream::pos_type pofilestream::vtell()
{
std::ptrdiff_t ret = ftell(static_cast<FILE *>(m_file));
if (ret < 0)
@@ -190,6 +215,11 @@ pstream::pos_type pofilestream::vtell() const
return static_cast<pos_type>(ret);
}
+postringstream::~postringstream()
+{
+}
+
+
// -----------------------------------------------------------------------------
// pstderr: write to stderr
// -----------------------------------------------------------------------------
@@ -203,6 +233,10 @@ pstderr::pstderr()
{
}
+pstderr::~pstderr()
+{
+}
+
// -----------------------------------------------------------------------------
// pstdout: write to stdout
// -----------------------------------------------------------------------------
@@ -216,32 +250,35 @@ pstdout::pstdout()
{
}
+pstdout::~pstdout()
+{
+}
+
// -----------------------------------------------------------------------------
// Memory stream
// -----------------------------------------------------------------------------
pimemstream::pimemstream(const void *mem, const pos_type len)
- : pistream(FLAG_SEEKABLE), m_pos(0), m_len(len), m_mem(static_cast<const char *>(mem))
+ : pistream(FLAG_SEEKABLE), m_pos(0), m_len(len), m_mem(static_cast<const pstring::mem_t *>(mem))
{
}
-pimemstream::pimemstream()
- : pistream(FLAG_SEEKABLE), m_pos(0), m_len(0), m_mem(static_cast<const char *>(nullptr))
+pimemstream::pimemstream(const pomemstream &ostrm)
+: pistream(FLAG_SEEKABLE), m_pos(0), m_len(ostrm.size()), m_mem(reinterpret_cast<pstring::mem_t *>(ostrm.memory()))
{
}
-pimemstream::pimemstream(const pomemstream &ostrm)
-: pistream(FLAG_SEEKABLE), m_pos(0), m_len(ostrm.size()), m_mem(reinterpret_cast<const char *>(ostrm.memory()))
+pimemstream::~pimemstream()
{
}
-pimemstream::pos_type pimemstream::vread(value_type *buf, const pos_type n)
+pimemstream::pos_type pimemstream::vread(void *buf, const pos_type n)
{
pos_type ret = (m_pos + n <= m_len) ? n : m_len - m_pos;
if (ret > 0)
{
- std::copy(m_mem + m_pos, m_mem + m_pos + ret, reinterpret_cast<char *>(buf));
+ std::copy(m_mem + m_pos, m_mem + m_pos + ret, static_cast<char *>(buf));
m_pos += ret;
}
@@ -258,45 +295,78 @@ void pimemstream::vseek(const pos_type n)
}
-pimemstream::pos_type pimemstream::vtell() const
+pimemstream::pos_type pimemstream::vtell()
{
return m_pos;
}
+pistringstream::~pistringstream()
+{
+}
+
// -----------------------------------------------------------------------------
// Output memory stream
// -----------------------------------------------------------------------------
pomemstream::pomemstream()
-: postream(FLAG_SEEKABLE), m_pos(0), m_mem(1024)
+: postream(FLAG_SEEKABLE), m_pos(0), m_capacity(1024), m_size(0)
+{
+ m_mem = palloc_array<char>(m_capacity);
+}
+
+pomemstream::~pomemstream()
{
- m_mem.clear();
+ pfree_array(m_mem);
}
-void pomemstream::vwrite(const value_type *buf, const pos_type n)
+void pomemstream::vwrite(const void *buf, const pos_type n)
{
- if (m_pos + n >= m_mem.size())
- m_mem.resize(m_pos + n);
+ if (m_pos + n >= m_capacity)
+ {
+ while (m_pos + n >= m_capacity)
+ m_capacity *= 2;
+ char *o = m_mem;
+ m_mem = palloc_array<char>(m_capacity);
+ if (m_mem == nullptr)
+ {
+ throw out_of_mem_e("pomemstream::vwrite");
+ }
+ std::copy(o, o + m_pos, m_mem);
+ pfree_array(o);
+ }
- std::copy(buf, buf + n, &m_mem[0] + m_pos);
+ std::copy(static_cast<const char *>(buf), static_cast<const char *>(buf) + n, m_mem + m_pos);
m_pos += n;
+ m_size = std::max(m_pos, m_size);
}
void pomemstream::vseek(const pos_type n)
{
m_pos = n;
- if (m_pos>=m_mem.size())
- m_mem.resize(m_pos);
+ m_size = std::max(m_pos, m_size);
+ if (m_size >= m_capacity)
+ {
+ while (m_size >= m_capacity)
+ m_capacity *= 2;
+ char *o = m_mem;
+ m_mem = palloc_array<char>(m_capacity);
+ if (m_mem == nullptr)
+ {
+ throw out_of_mem_e("pomemstream::vseek");
+ }
+ std::copy(o, o + m_pos, m_mem);
+ pfree_array(o);
+ }
}
-pstream::pos_type pomemstream::vtell() const
+pstream::pos_type pomemstream::vtell()
{
return m_pos;
}
bool putf8_reader::readline(pstring &line)
{
- putf8string::code_t c = 0;
+ pstring::code_t c = 0;
m_linebuf = "";
if (!this->readcode(c))
{
@@ -308,14 +378,23 @@ bool putf8_reader::readline(pstring &line)
if (c == 10)
break;
else if (c != 13) /* ignore CR */
- m_linebuf += putf8string(c);
+ m_linebuf += pstring(c);
if (!this->readcode(c))
break;
}
- line = m_linebuf.c_str();
+ line = m_linebuf;
return true;
}
+putf8_fmt_writer::putf8_fmt_writer(postream &strm)
+: pfmt_writer_t()
+, putf8_writer(strm)
+{
+}
+
+putf8_fmt_writer::~putf8_fmt_writer()
+{
+}
void putf8_fmt_writer::vdowrite(const pstring &ls) const
{
@@ -324,4 +403,4 @@ void putf8_fmt_writer::vdowrite(const pstring &ls) const
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h
index 93497eb1423..3e9ee99cba0 100644
--- a/src/lib/netlist/plib/pstream.h
+++ b/src/lib/netlist/plib/pstream.h
@@ -7,76 +7,46 @@
#ifndef PSTREAM_H_
#define PSTREAM_H_
-
-#include "palloc.h"
#include "pconfig.h"
-#include "pexception.h"
-#include "pfmtlog.h"
#include "pstring.h"
+#include "pfmtlog.h"
+#include "pexception.h"
-#define USE_CSTREAM (0)
-
-#include <array>
-#include <type_traits>
#include <vector>
-#if USE_CSTREAM
-#include <fstream>
-//#include <strstream>
-#include <sstream>
-#endif
-
namespace plib {
-
-#if USE_CSTREAM
-typedef std::ostream postream;
-typedef std::ofstream pofilestream;
-typedef std::ostringstream postringstream;
-typedef std::ostringstream pomemstream;
-
-#endif
-
// -----------------------------------------------------------------------------
// pstream: things common to all streams
// -----------------------------------------------------------------------------
-class pstream
+class pstream : nocopyassignmove
{
public:
using pos_type = std::size_t;
- using size_type = std::size_t;
static constexpr pos_type SEEK_EOF = static_cast<pos_type>(-1);
- COPYASSIGN(pstream, delete)
- pstream &operator=(pstream &&) noexcept = delete;
-
bool seekable() const { return ((m_flags & FLAG_SEEKABLE) != 0); }
- void seekp(const pos_type n)
+ void seek(const pos_type n)
{
- vseek(n);
+ return vseek(n);
}
- pos_type tellp() const
+ pos_type tell()
{
return vtell();
}
protected:
- pstream() : m_flags(0)
- {
- }
explicit pstream(const unsigned flags) : m_flags(flags)
{
}
- pstream(pstream &&src) noexcept = default;
-
- virtual ~pstream() = default;
+ ~pstream();
virtual void vseek(const pos_type n) = 0;
- virtual pos_type vtell() const = 0;
+ virtual pos_type vtell() = 0;
static constexpr unsigned FLAG_EOF = 0x01;
static constexpr unsigned FLAG_SEEKABLE = 0x04;
@@ -99,71 +69,51 @@ private:
// pistream: input stream
// -----------------------------------------------------------------------------
-template <typename T>
-class pistream_base : public pstream
+class pistream : public pstream
{
public:
- using value_type = T;
-
- ~pistream_base() noexcept override = default;
-
- COPYASSIGN(pistream_base, delete)
- pistream_base &operator=(pistream_base &&src) noexcept = delete;
+ virtual ~pistream();
bool eof() const { return ((flags() & FLAG_EOF) != 0); }
- pos_type read(T *buf, const pos_type n)
+ pos_type read(void *buf, const pos_type n)
{
return vread(buf, n);
}
protected:
- pistream_base() : pstream(0) {}
- explicit pistream_base(const unsigned flags) : pstream(flags) {}
- pistream_base(pistream_base &&src) noexcept : pstream(std::move(src)) {}
-
+ explicit pistream(const unsigned flags) : pstream(flags) {}
/* read up to n bytes from stream */
- virtual size_type vread(T *buf, const size_type n) = 0;
-};
+ virtual pos_type vread(void *buf, const pos_type n) = 0;
-using pistream = pistream_base<char>;
+};
// -----------------------------------------------------------------------------
// postream: output stream
// -----------------------------------------------------------------------------
-#if !USE_CSTREAM
-template <typename T>
-class postream_base : public pstream
+class postream : public pstream
{
public:
- using value_type = T;
-
- postream_base() = default;
- ~postream_base() noexcept override = default;
-
- COPYASSIGN(postream_base, delete)
- postream_base &operator=(postream_base &&src) noexcept = delete;
+ virtual ~postream();
- void write(const T *buf, const size_type n)
+ void write(const void *buf, const pos_type n)
{
vwrite(buf, n);
}
-protected:
- explicit postream_base(unsigned flags) : pstream(flags) {}
- postream_base(postream_base &&src) noexcept : pstream(std::move(src)) {}
+ void write(pistream &strm);
+protected:
+ explicit postream(unsigned flags) : pstream(flags) {}
/* write n bytes to stream */
- virtual void vwrite(const T *buf, const size_type n) = 0;
+ virtual void vwrite(const void *buf, const pos_type n) = 0;
private:
};
-using postream = postream_base<char>;
-
// -----------------------------------------------------------------------------
// pomemstream: output string stream
// -----------------------------------------------------------------------------
@@ -173,31 +123,22 @@ class pomemstream : public postream
public:
pomemstream();
+ virtual ~pomemstream() override;
- COPYASSIGN(pomemstream, delete)
-
- pomemstream(pomemstream &&src) noexcept
- : postream(std::move(src))
- , m_pos(src.m_pos)
- , m_mem(std::move(src.m_mem))
- {
- }
- pomemstream &operator=(pomemstream &&src) = delete;
-
- ~pomemstream() override = default;
-
- const char *memory() const { return m_mem.data(); }
- pos_type size() const { return m_mem.size(); }
+ char *memory() const { return m_mem; }
+ pos_type size() const { return m_size; }
protected:
/* write n bytes to stream */
- void vwrite(const value_type *buf, const pos_type) override;
- void vseek(const pos_type n) override;
- pos_type vtell() const override;
+ virtual void vwrite(const void *buf, const pos_type) override;
+ virtual void vseek(const pos_type n) override;
+ virtual pos_type vtell() override;
private:
pos_type m_pos;
- std::vector<char> m_mem;
+ pos_type m_capacity;
+ pos_type m_size;
+ char *m_mem;
};
class postringstream : public postream
@@ -205,26 +146,18 @@ class postringstream : public postream
public:
postringstream() : postream(0) { }
- postringstream(postringstream &&src) noexcept
- : postream(std::move(src))
- , m_buf(std::move(src.m_buf))
- { src.m_buf = ""; }
-
- COPYASSIGN(postringstream, delete)
- postringstream &operator=(postringstream &&src) = delete;
-
- ~postringstream() override = default;
+ virtual ~postringstream() override;
const pstring &str() { return m_buf; }
protected:
/* write n bytes to stream */
- void vwrite(const value_type *buf, const pos_type n) override
+ virtual void vwrite(const void *buf, const pos_type n) override
{
- m_buf += pstring(reinterpret_cast<const pstring::mem_t *>(buf), n);
+ m_buf += pstring(static_cast<const pstring::mem_t *>(buf), n, pstring::UTF8);
}
- void vseek(const pos_type n) override { unused_var(n); }
- pos_type vtell() const override { return m_buf.size(); }
+ virtual void vseek(const pos_type n) override { }
+ virtual pos_type vtell() override { return m_buf.mem_t_size(); }
private:
pstring m_buf;
@@ -238,28 +171,15 @@ class pofilestream : public postream
{
public:
- pofilestream(const pstring &fname);
- pofilestream(pofilestream &&src) noexcept
- : postream(std::move(src))
- , m_file(src.m_file)
- , m_pos(src.m_pos)
- , m_actually_close(src.m_actually_close)
- , m_filename(std::move(src.m_filename))
- {
- src.m_file = nullptr;
- src.m_actually_close = false;
- }
- COPYASSIGN(pofilestream, delete)
- pofilestream &operator=(pofilestream &&src) = delete;
-
- ~pofilestream() override;
+ explicit pofilestream(const pstring &fname);
+ virtual ~pofilestream() override;
protected:
pofilestream(void *file, const pstring &name, const bool do_close);
/* write n bytes to stream */
- void vwrite(const value_type *buf, const pos_type n) override;
- void vseek(const pos_type n) override;
- pos_type vtell() const 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;
private:
void *m_file;
@@ -273,17 +193,12 @@ private:
// -----------------------------------------------------------------------------
// pstderr: write to stderr
// -----------------------------------------------------------------------------
-#endif
class pstderr : public pofilestream
{
public:
pstderr();
- pstderr(pstderr &&src) noexcept = default;
- pstderr &operator=(pstderr &&src) = delete;
- COPYASSIGN(pstderr, delete)
-
- ~pstderr() noexcept override= default;
+ virtual ~pstderr();
};
// -----------------------------------------------------------------------------
@@ -294,11 +209,7 @@ class pstdout : public pofilestream
{
public:
pstdout();
- pstdout(pstdout &&src) noexcept = default;
- pstdout &operator=(pstdout &&src) = delete;
- COPYASSIGN(pstdout, delete)
-
- ~pstdout() noexcept override = default;
+ virtual ~pstdout();
};
// -----------------------------------------------------------------------------
@@ -309,29 +220,16 @@ class pifilestream : public pistream
{
public:
- pifilestream(const pstring &fname);
- ~pifilestream() override;
-
- pifilestream(pifilestream &&src) noexcept
- : pistream(std::move(src))
- , m_file(src.m_file)
- , m_pos(src.m_pos)
- , m_actually_close(src.m_actually_close)
- , m_filename(std::move(src.m_filename))
- {
- src.m_actually_close = false;
- src.m_file = nullptr;
- }
- COPYASSIGN(pifilestream, delete)
- pifilestream &operator=(pifilestream &&src) = delete;
+ explicit pifilestream(const pstring &fname);
+ virtual ~pifilestream() override;
protected:
pifilestream(void *file, const pstring &name, const bool do_close);
/* read up to n bytes from stream */
- pos_type vread(value_type *buf, const pos_type n) override;
- void vseek(const pos_type n) override;
- pos_type vtell() const 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:
void *m_file;
@@ -351,10 +249,7 @@ class pstdin : public pifilestream
public:
pstdin();
- pstdin(pstdin &&src) noexcept = default;
- pstdin &operator=(pstdin &&src) = delete;
- COPYASSIGN(pstdin, delete)
- ~pstdin() override = default;
+ virtual ~pstdin() override;
};
// -----------------------------------------------------------------------------
@@ -366,36 +261,15 @@ class pimemstream : public pistream
public:
pimemstream(const void *mem, const pos_type len);
- pimemstream();
-
- pimemstream(pimemstream &&src) noexcept
- : pistream(std::move(src))
- , m_pos(src.m_pos)
- , m_len(src.m_len)
- , m_mem(src.m_mem)
- {
- src.m_mem = nullptr;
- }
- COPYASSIGN(pimemstream, delete)
- pimemstream &operator=(pimemstream &&src) = delete;
-
explicit pimemstream(const pomemstream &ostrm);
-
- ~pimemstream() override = default;
+ virtual ~pimemstream() override;
pos_type size() const { return m_len; }
protected:
-
- void set_mem(const void *mem, const pos_type len)
- {
- m_mem = static_cast<const char *>(mem);
- m_len = len;
- }
-
/* read up to n bytes from stream */
- pos_type vread(value_type *buf, const pos_type n) override;
- void vseek(const pos_type n) override;
- pos_type vtell() const 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;
@@ -410,25 +284,12 @@ private:
class pistringstream : public pimemstream
{
public:
- pistringstream(const pstring &str)
- : pimemstream()
- , m_str(str)
- {
- set_mem(m_str.c_str(), std::strlen(m_str.c_str()));
- }
- pistringstream(pistringstream &&src) noexcept
- : pimemstream(std::move(src)), m_str(src.m_str)
- {
- set_mem(m_str.c_str(), std::strlen(m_str.c_str()));
- }
- COPYASSIGN(pistringstream, delete)
- pistringstream &operator=(pistringstream &&src) = delete;
-
- ~pistringstream() override = default;
+ explicit pistringstream(const pstring &str) : pimemstream(str.c_str(), str.mem_t_size()), m_str(str) { }
+ virtual ~pistringstream() override;
private:
/* only needed for a reference till destruction */
- const pstring m_str;
+ pstring m_str;
};
// -----------------------------------------------------------------------------
@@ -437,84 +298,47 @@ private:
/* this digests linux & dos/windows text files */
-
-template <typename T>
-struct constructor_helper
-{
- plib::unique_ptr<pistream> operator()(T &&s) { return std::move(plib::make_unique<T>(std::move(s))); }
-};
-
-// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
-class putf8_reader
+class putf8_reader : plib::nocopyassignmove
{
public:
+ explicit putf8_reader(pistream &strm) : m_strm(strm) {}
+ virtual ~putf8_reader() {}
- COPYASSIGN(putf8_reader, delete)
- putf8_reader &operator=(putf8_reader &&src) = delete;
- virtual ~putf8_reader() = default;
-
- template <typename T>
- friend struct constructor_helper;
-
- template <typename T>
- putf8_reader(T &&strm) // NOLINT(cppcoreguidelines-special-member-functions, misc-forwarding-reference-overload, bugprone-forwarding-reference-overload)
- : m_strm(std::move(constructor_helper<T>()(std::move(strm)))) // NOLINT(bugprone-move-forwarding-reference)
- {}
-
- bool eof() const { return m_strm->eof(); }
+ bool eof() const { return m_strm.eof(); }
bool readline(pstring &line);
- bool readbyte1(pistream::value_type &b)
+ bool readbyte1(char &b)
{
- return (m_strm->read(&b, 1) == 1);
+ return (m_strm.read(&b, 1) == 1);
}
- bool readcode(putf8string::traits_type::code_t &c)
+ bool readcode(pstring::code_t &c)
{
- std::array<pistream::value_type, 4> b{0};
- if (m_strm->read(&b[0], 1) != 1)
+ char b[4];
+ if (m_strm.read(&b[0], 1) != 1)
return false;
- const std::size_t l = putf8string::traits_type::codelen(reinterpret_cast<putf8string::traits_type::mem_t *>(&b));
+ const std::size_t l = pstring::traits_type::codelen(b);
for (std::size_t i = 1; i < l; i++)
- if (m_strm->read(&b[i], 1) != 1)
+ if (m_strm.read(&b[i], 1) != 1)
return false;
- c = putf8string::traits_type::code(reinterpret_cast<putf8string::traits_type::mem_t *>(&b));
+ c = pstring::traits_type::code(b);
return true;
}
private:
- plib::unique_ptr<pistream> m_strm;
- putf8string m_linebuf;
-};
-
-template <>
-struct constructor_helper<putf8_reader>
-{
- plib::unique_ptr<pistream> operator()(putf8_reader &&s) { return std::move(s.m_strm); }
-};
-
-template <>
-struct constructor_helper<plib::unique_ptr<pistream>>
-{
- plib::unique_ptr<pistream> operator()(plib::unique_ptr<pistream> &&s) { return std::move(s); }
+ pistream &m_strm;
+ pstring m_linebuf;
};
-
// -----------------------------------------------------------------------------
// putf8writer_t: writer on top of ostream
// -----------------------------------------------------------------------------
-class putf8_writer
+class putf8_writer : plib::nocopyassignmove
{
public:
- explicit putf8_writer(postream *strm) : m_strm(strm) {}
-
- putf8_writer(putf8_writer &&src) noexcept : m_strm(src.m_strm) {}
-
- COPYASSIGN(putf8_writer, delete)
- putf8_writer &operator=(putf8_writer &&src) = delete;
-
- virtual ~putf8_writer() = default;
+ explicit putf8_writer(postream &strm) : m_strm(strm) {}
+ virtual ~putf8_writer() {}
void writeline(const pstring &line) const
{
@@ -524,34 +348,24 @@ public:
void write(const pstring &text) const
{
- // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
- const putf8string conv_utf8(text);
- m_strm->write(reinterpret_cast<const pistream::value_type *>(conv_utf8.c_str()), conv_utf8.mem_t_size());
+ m_strm.write(text.c_str(), text.mem_t_size());
}
- void write(const pstring::value_type c) const
+ void write(const pstring::code_t c) const
{
- pstring t = pstring("") + c;
- write(t);
+ write(pstring(c));
}
private:
- postream *m_strm;
+ postream &m_strm;
};
class putf8_fmt_writer : public pfmt_writer_t<putf8_fmt_writer>, public putf8_writer
{
public:
- explicit putf8_fmt_writer(postream *strm)
- : pfmt_writer_t()
- , putf8_writer(strm)
- {
- }
-
- COPYASSIGNMOVE(putf8_fmt_writer, delete)
-
- ~putf8_fmt_writer() override = default;
+ explicit putf8_fmt_writer(postream &strm);
+ virtual ~putf8_fmt_writer() override;
//protected:
void vdowrite(const pstring &ls) const;
@@ -563,29 +377,22 @@ private:
// pbinary_writer_t: writer on top of ostream
// -----------------------------------------------------------------------------
-class pbinary_writer
+class pbinary_writer : plib::nocopyassignmove
{
public:
explicit pbinary_writer(postream &strm) : m_strm(strm) {}
- pbinary_writer(pbinary_writer &&src) noexcept : m_strm(src.m_strm) {}
-
- COPYASSIGN(pbinary_writer, delete)
- postringstream &operator=(pbinary_writer &&src) = delete;
-
- virtual ~pbinary_writer() = default;
+ virtual ~pbinary_writer() {}
template <typename T>
- void write(const T &val)
+ void write(const T val)
{
- m_strm.write(reinterpret_cast<const postream::value_type *>(&val), sizeof(T));
+ m_strm.write(&val, sizeof(T));
}
void write(const pstring &s)
{
- const auto sm = reinterpret_cast<const postream::value_type *>(s.c_str());
- const std::size_t sl = std::strlen(s.c_str());
- write(sl);
- m_strm.write(sm, sl);
+ write(s.mem_t_size());
+ m_strm.write(s.c_str(), s.mem_t_size());
}
template <typename T>
@@ -593,38 +400,34 @@ public:
{
std::size_t sz = val.size();
write(sz);
- m_strm.write(reinterpret_cast<const postream::value_type *>(val.data()), sizeof(T) * sz);
+ m_strm.write(val.data(), sizeof(T) * sz);
}
private:
postream &m_strm;
};
-class pbinary_reader
+class pbinary_reader : plib::nocopyassignmove
{
public:
explicit pbinary_reader(pistream &strm) : m_strm(strm) {}
- pbinary_reader(pbinary_reader &&src) noexcept : m_strm(src.m_strm) { }
-
- COPYASSIGN(pbinary_reader, delete)
- pbinary_reader &operator=(pbinary_reader &&src) = delete;
-
- virtual ~pbinary_reader() = default;
+ virtual ~pbinary_reader() {}
template <typename T>
void read(T &val)
{
- m_strm.read(reinterpret_cast<pistream::value_type *>(&val), sizeof(T));
+ m_strm.read(&val, sizeof(T));
}
void read( pstring &s)
{
std::size_t sz = 0;
read(sz);
- std::vector<plib::string_info<pstring>::mem_t> buf(sz+1);
- m_strm.read(buf.data(), sz);
+ pstring::mem_t *buf = new pstring::mem_t[sz+1];
+ m_strm.read(buf, sz);
buf[sz] = 0;
- s = pstring(buf.data());
+ s = pstring(buf, pstring::UTF8);
+ delete [] buf;
}
template <typename T>
@@ -633,38 +436,13 @@ public:
std::size_t sz = 0;
read(sz);
val.resize(sz);
- m_strm.read(reinterpret_cast<pistream::value_type *>(val.data()), sizeof(T) * sz);
+ m_strm.read(val.data(), sizeof(T) * sz);
}
private:
pistream &m_strm;
};
-inline void copystream(postream &dest, pistream &src)
-{
- std::array<postream::value_type, 1024> buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
- pstream::pos_type r;
- while ((r=src.read(buf.data(), 1024)) > 0)
- dest.write(buf.data(), r);
}
-struct perrlogger
-{
- template <typename ... Args>
- explicit perrlogger(Args&& ... args)
- {
- h()(std::forward<Args>(args)...);
- }
-private:
- static putf8_fmt_writer &h()
- {
- static plib::pstderr perr_strm;
- static plib::putf8_fmt_writer perr(&perr_strm);
- return perr;
- }
-};
-
-
-} // namespace plib
-
#endif /* PSTREAM_H_ */
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index c304f11d1fd..47d35d7c82f 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -10,8 +10,17 @@
#include "plists.h"
#include <algorithm>
-#include <atomic>
#include <stack>
+#include <atomic>
+
+template <typename T>
+std::size_t strlen_mem(const T *s)
+{
+ std::size_t len(0);
+ while (*s++)
+ ++len;
+ return len;
+}
template<typename F>
int pstring_t<F>::compare(const pstring_t &right) const
@@ -58,6 +67,18 @@ pstring_t<F> pstring_t<F>::substr(size_type start, size_type nlen) const
}
template<typename F>
+pstring_t<F> pstring_t<F>::ucase() const
+{
+ pstring_t ret;
+ for (const auto &c : *this)
+ if (c >= 'a' && c <= 'z')
+ ret += (c - 'a' + 'A');
+ else
+ ret += c;
+ return ret;
+}
+
+template<typename F>
typename pstring_t<F>::size_type pstring_t<F>::find_first_not_of(const pstring_t &no) const
{
size_type pos = 0;
@@ -129,6 +150,114 @@ typename pstring_t<F>::size_type pstring_t<F>::find(code_t search, size_type sta
return find(ss, start);
}
+
+template<typename F>
+pstring_t<F> pstring_t<F>::replace_all(const pstring_t &search, const pstring_t &replace) const
+{
+ pstring_t ret;
+ const size_type slen = search.length();
+
+ size_type last_s = 0;
+ size_type s = find(search, last_s);
+ while (s != npos)
+ {
+ ret += substr(last_s, s - last_s);
+ ret += replace;
+ last_s = s + slen;
+ s = find(search, last_s);
+ }
+ ret += substr(last_s);
+ return ret;
+}
+
+template<typename F>
+pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const size_type cnt) const
+{
+ // FIXME: pstringbuffer ret(*this);
+
+ pstring_t ret(*this);
+ size_type wsl = ws.length();
+ for (auto i = ret.length(); i < cnt; i+=wsl)
+ ret += ws;
+ return ret;
+}
+
+static double pstod(const pstring_t<pu8_traits> &str, std::size_t *e)
+{
+ return std::stod(str.cpp_string(), e);
+}
+
+static double pstod(const pstring &str, std::size_t *e)
+{
+ return std::stod(str.cpp_string(), e);
+}
+
+static double pstod(const pwstring &str, std::size_t *e)
+{
+ return std::stod(str.cpp_string(), e);
+}
+
+static double pstod(const pu16string &str, std::size_t *e)
+{
+ pstring c;
+ c = str;
+ return std::stod(c.cpp_string(), e);
+}
+
+static long pstol(const pstring_t<pu8_traits> &str, std::size_t *e, int base = 10)
+{
+ return std::stol(str.cpp_string(), e, base);
+}
+
+static long pstol(const pstring &str, std::size_t *e, int base = 10)
+{
+ return std::stol(str.cpp_string(), e, base);
+}
+
+static long pstol(const pwstring &str, std::size_t *e, int base = 10)
+{
+ return std::stol(str.cpp_string(), e, base);
+}
+
+static long pstol(const pu16string &str, std::size_t *e, int base = 10)
+{
+ pstring c;
+ c = str;
+ return std::stol(c.cpp_string(), e, base);
+}
+
+template<typename F>
+double pstring_t<F>::as_double(bool *error) const
+{
+ std::size_t e = 0;
+ if (error != nullptr)
+ *error = false;
+ double ret = pstod(*this, &e);
+ if (e != mem_t_size())
+ if (error != nullptr)
+ *error = true;
+ return ret;
+}
+
+template<typename F>
+long pstring_t<F>::as_long(bool *error) const
+{
+ static pstring_t prefix(pstring("0x"));
+ long ret;
+ std::size_t e = 0;
+
+ if (error != nullptr)
+ *error = false;
+ if (startsWith(prefix))
+ ret = pstol(substr(2), &e, 16);
+ else
+ ret = pstol(*this, &e, 10);
+ if (e != mem_t_size())
+ if (error != nullptr)
+ *error = true;
+ return ret;
+}
+
// ----------------------------------------------------------------------------------------
// template stuff ...
// ----------------------------------------------------------------------------------------
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index c4caeab8e8f..cabce0e7b93 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -7,50 +7,45 @@
#ifndef PSTRING_H_
#define PSTRING_H_
-#include "ptypes.h"
-
-#include <cstring>
-#include <exception>
#include <iterator>
-#include <limits>
-#include <stdexcept>
+#include <exception>
#include <string>
-#include <type_traits>
// ----------------------------------------------------------------------------------------
// pstring: semi-immutable strings ...
//
// The only reason this class exists is the absence of support for multi-byte
-// strings in std:: which I would consider sub-optimal for the use-cases I encounter.
+// strings in std:: which I would consider usuable for the use-cases I encounter.
// ----------------------------------------------------------------------------------------
-// enable this to use std::string instead of pstring globally.
-
-#define PSTRING_USE_STD_STRING (0)
-
template <typename T>
class pstring_const_iterator final
{
public:
- using value_type = typename T::ref_value_type;
+ typedef typename T::ref_value_type value_type;
- using pointer = value_type const *;
- using reference = value_type const &;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
- using string_type = typename T::string_type;
- using traits_type = typename T::traits_type;
+ typedef value_type const *pointer;
+ typedef value_type const &reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename T::string_type string_type;
+ typedef typename T::traits_type traits_type;
- constexpr pstring_const_iterator() noexcept : p() { }
+ pstring_const_iterator() noexcept : p() { }
explicit constexpr pstring_const_iterator(const typename string_type::const_iterator &x) noexcept : p(x) { }
+#if !defined(_MSC_VER) || !defined(_ITERATOR_DEBUG_LEVEL) || (0 == _ITERATOR_DEBUG_LEVEL) // debug iterators are broken
+ pstring_const_iterator(const pstring_const_iterator &rhs) noexcept = default;
+ pstring_const_iterator(pstring_const_iterator &&rhs) noexcept = default;
+ pstring_const_iterator &operator=(const pstring_const_iterator &rhs) noexcept = default;
+ pstring_const_iterator &operator=(pstring_const_iterator &&rhs) noexcept = default;
+#endif
pstring_const_iterator& operator++() noexcept { p += static_cast<difference_type>(traits_type::codelen(&(*p))); return *this; }
- // NOLINTNEXTLINE(cert-dcl21-cpp)
- pstring_const_iterator operator++(int) & noexcept { pstring_const_iterator tmp(*this); operator++(); return tmp; }
+ pstring_const_iterator operator++(int) noexcept { pstring_const_iterator tmp(*this); operator++(); return tmp; }
- constexpr bool operator==(const pstring_const_iterator& rhs) const noexcept { return p == rhs.p; }
- constexpr bool operator!=(const pstring_const_iterator& rhs) const noexcept { return p != rhs.p; }
+ bool operator==(const pstring_const_iterator& rhs) const noexcept { return p == rhs.p; }
+ bool operator!=(const pstring_const_iterator& rhs) const noexcept { return p != rhs.p; }
reference operator*() const noexcept { return *reinterpret_cast<pointer>(&(*p)); }
pointer operator->() const noexcept { return reinterpret_cast<pointer>(&(*p)); }
@@ -65,21 +60,18 @@ template <typename F>
struct pstring_t
{
public:
- using traits_type = F;
+ typedef F traits_type;
- using mem_t = typename traits_type::mem_t;
- using code_t = typename traits_type::code_t;
- using value_type = typename traits_type::code_t;
- using size_type = std::size_t;
- using difference_type = std::ptrdiff_t;
- using string_type = typename traits_type::string_type;
+ typedef typename traits_type::mem_t mem_t;
+ typedef typename traits_type::code_t code_t;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef typename traits_type::string_type string_type;
- // FIXME: this is ugly
- struct ref_value_type final
+ class ref_value_type final
{
public:
ref_value_type() = delete;
- ~ref_value_type() = delete;
ref_value_type(const ref_value_type &) = delete;
ref_value_type(ref_value_type &&) = delete;
ref_value_type &operator=(const ref_value_type &) = delete;
@@ -88,27 +80,37 @@ public:
private:
const mem_t m;
};
- using const_reference = const ref_value_type &;
- using reference = const_reference;
+ typedef const ref_value_type& const_reference;
+ typedef const_reference reference;
+
+ enum enc_t
+ {
+ UTF8,
+ UTF16
+ };
// simple construction/destruction
- pstring_t() = default;
- ~pstring_t() noexcept = default;
+ pstring_t()
+ {
+ }
+ ~pstring_t()
+ {
+ }
// FIXME: Do something with encoding
- pstring_t(const mem_t *string)
+ pstring_t(const mem_t *string, const enc_t enc)
: m_str(string)
{
}
- pstring_t(const mem_t *string, const size_type len)
+ pstring_t(const mem_t *string, const size_type len, const enc_t enc)
: m_str(string, len)
{
}
template<typename C, std::size_t N,
class = typename std::enable_if<std::is_same<C, const mem_t>::value>::type>
- pstring_t(C (&string)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ pstring_t(C (&string)[N])
{
static_assert(N > 0,"pstring from array of length 0");
if (string[N-1] != 0)
@@ -116,15 +118,17 @@ public:
m_str.assign(string, N - 1);
}
+ pstring_t(const pstring_t &string)
+ : m_str(string.m_str)
+ { }
- explicit pstring_t(const string_type &string)
+ explicit pstring_t(const string_type &string, const enc_t enc)
: m_str(string)
{ }
- pstring_t(const pstring_t &string) = default;
- pstring_t(pstring_t &&string) noexcept = default;
- pstring_t &operator=(const pstring_t &string) = default;
- pstring_t &operator=(pstring_t &&string) noexcept = default;
+ pstring_t(pstring_t &&string)
+ : m_str(string.m_str)
+ { }
explicit pstring_t(code_t code)
{
@@ -140,8 +144,7 @@ public:
*this += static_cast<code_t>(c); // FIXME: codepage conversion for u8
}
- operator string_type () const { return m_str; }
-
+ pstring_t &operator=(const pstring_t &string) { m_str = string.m_str; return *this; }
template <typename T,
class = typename std::enable_if<!std::is_same<T, pstring_t::traits_type>::value>::type>
@@ -154,8 +157,8 @@ public:
}
// no non-const const_iterator for now
- using iterator = pstring_const_iterator<pstring_t<F> >;
- using const_iterator = pstring_const_iterator<pstring_t<F> >;
+ typedef pstring_const_iterator<pstring_t> iterator;
+ typedef pstring_const_iterator<pstring_t> const_iterator;
iterator begin() { return iterator(m_str.begin()); }
iterator end() { return iterator(m_str.end()); }
@@ -198,26 +201,67 @@ public:
const_reference at(const size_type pos) const { return *reinterpret_cast<const ref_value_type *>(F::nthcode(m_str.c_str(),pos)); }
+ /* The following is not compatible to std::string */
+
+ bool equals(const pstring_t &string) const { return (compare(string) == 0); }
+
+ bool startsWith(const pstring_t &arg) const { return arg.mem_t_size() > mem_t_size() ? false : m_str.compare(0, arg.mem_t_size(), arg.m_str) == 0; }
+ bool endsWith(const pstring_t &arg) const { return arg.mem_t_size() > mem_t_size() ? false : m_str.compare(mem_t_size()-arg.mem_t_size(), arg.mem_t_size(), arg.m_str) == 0; }
+
+ pstring_t replace_all(const pstring_t &search, const pstring_t &replace) const;
+ pstring_t cat(const pstring_t &s) const { return *this + s; }
+ pstring_t cat(code_t c) const { return *this + c; }
+
+ // conversions
+
+ double as_double(bool *error = nullptr) const;
+ long as_long(bool *error = nullptr) const;
+
/* the following are extensions to <string> */
size_type mem_t_size() const { return m_str.size(); }
+ pstring_t left(size_type len) const { return substr(0, len); }
+ pstring_t right(size_type nlen) const
+ {
+ return nlen >= length() ? *this : substr(length() - nlen, nlen);
+ }
+
+ pstring_t ltrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ return substr(find_first_not_of(ws));
+ }
+
+ pstring_t rtrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ auto f = find_last_not_of(ws);
+ return f == npos ? pstring_t() : substr(0, f + 1);
+ }
+
+ pstring_t trim(const pstring_t &ws = pstring_t(" \t\n\r")) const { return this->ltrim(ws).rtrim(ws); }
+
+ pstring_t rpad(const pstring_t &ws, const size_type cnt) const;
+
+ pstring_t ucase() const;
+
const string_type &cpp_string() const { return m_str; }
- static constexpr const size_type npos = static_cast<size_type>(-1);
+ static const size_type npos = static_cast<size_type>(-1);
-private:
+protected:
string_type m_str;
+
+private:
};
struct pu8_traits
{
- using mem_t = char;
- using code_t = char;
- using string_type = std::string;
+ typedef char mem_t;
+ typedef char code_t;
+ typedef std::string string_type;
static std::size_t len(const string_type &p) { return p.size(); }
- static std::size_t codelen(const mem_t *p) { plib::unused_var(p); return 1; }
- static std::size_t codelen(const code_t c) { plib::unused_var(c); return 1; }
+ static std::size_t codelen(const mem_t *p) { return 1; }
+ static std::size_t codelen(const code_t c) { return 1; }
static code_t code(const mem_t *p) { return *p; }
static void encode(const code_t c, string_type &s) { s += static_cast<mem_t>(c); }
static const mem_t *nthcode(const mem_t *p, const std::size_t n) { return &(p[n]); }
@@ -226,9 +270,9 @@ struct pu8_traits
/* No checking, this may deliver invalid codes */
struct putf8_traits
{
- using mem_t = char;
- using code_t = char32_t;
- using string_type = std::string;
+ typedef char mem_t;
+ typedef char32_t code_t;
+ typedef std::string string_type;
static std::size_t len(const string_type &p)
{
std::size_t ret = 0;
@@ -241,7 +285,7 @@ struct putf8_traits
}
static std::size_t codelen(const mem_t *p)
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
+ const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p);
if ((*p1 & 0x80) == 0x00)
return 1;
else if ((*p1 & 0xE0) == 0xC0)
@@ -268,7 +312,7 @@ struct putf8_traits
}
static code_t code(const mem_t *p)
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
+ const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p);
if ((*p1 & 0x80) == 0x00)
return *p1;
else if ((*p1 & 0xE0) == 0xC0)
@@ -317,9 +361,9 @@ struct putf8_traits
struct putf16_traits
{
- using mem_t = char16_t;
- using code_t = char32_t;
- using string_type = std::u16string;
+ typedef char16_t mem_t;
+ typedef char32_t code_t;
+ typedef std::u16string string_type;
static std::size_t len(const string_type &p)
{
std::size_t ret = 0;
@@ -327,7 +371,7 @@ struct putf16_traits
while (i != p.end())
{
// FIXME: check that size is equal
- auto c = static_cast<uint16_t>(*i++);
+ uint16_t c = static_cast<uint16_t>(*i++);
if (!((c & 0xd800) == 0xd800))
ret++;
}
@@ -335,7 +379,7 @@ struct putf16_traits
}
static std::size_t codelen(const mem_t *p)
{
- auto c = static_cast<uint16_t>(*p);
+ uint16_t c = static_cast<uint16_t>(*p);
return ((c & 0xd800) == 0xd800) ? 2 : 1;
}
static std::size_t codelen(const code_t c)
@@ -347,7 +391,7 @@ struct putf16_traits
}
static code_t code(const mem_t *p)
{
- auto c = static_cast<uint32_t>(*p++);
+ uint32_t c = static_cast<uint32_t>(*p++);
if ((c & 0xd800) == 0xd800)
{
c = (c - 0xd800) << 10;
@@ -357,7 +401,7 @@ struct putf16_traits
}
static void encode(code_t c, string_type &s)
{
- auto cu = static_cast<uint32_t>(c);
+ uint32_t cu = static_cast<uint32_t>(c);
if (c > 0xffff)
{ //make a surrogate pair
uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
@@ -381,9 +425,9 @@ struct putf16_traits
struct pwchar_traits
{
- using mem_t = wchar_t;
- using code_t = char32_t;
- using string_type = std::wstring;
+ typedef wchar_t mem_t;
+ typedef char32_t code_t;
+ typedef std::wstring string_type;
static std::size_t len(const string_type &p)
{
if (sizeof(wchar_t) == 2)
@@ -393,7 +437,7 @@ struct pwchar_traits
while (i != p.end())
{
// FIXME: check that size is equal
- auto c = static_cast<uint32_t>(*i++);
+ uint32_t c = static_cast<uint32_t>(*i++);
if (!((c & 0xd800) == 0xd800))
ret++;
}
@@ -407,7 +451,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto c = static_cast<uint16_t>(*p);
+ uint16_t c = static_cast<uint16_t>(*p);
return ((c & 0xd800) == 0xd800) ? 2 : 1;
}
else
@@ -426,7 +470,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto c = static_cast<uint32_t>(*p++);
+ uint32_t c = static_cast<uint32_t>(*p++);
if ((c & 0xd800) == 0xd800)
{
c = (c - 0xd800) << 10;
@@ -442,7 +486,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto cu = static_cast<uint32_t>(c);
+ uint32_t cu = static_cast<uint32_t>(c);
if (c > 0xffff)
{ //make a surrogate pair
uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
@@ -475,280 +519,41 @@ extern template struct pstring_t<putf8_traits>;
extern template struct pstring_t<putf16_traits>;
extern template struct pstring_t<pwchar_traits>;
-#if (PSTRING_USE_STD_STRING)
-typedef std::string pstring;
-#else
-using pstring = pstring_t<putf8_traits>;
-#endif
-using putf8string = pstring_t<putf8_traits>;
-using pu16string = pstring_t<putf16_traits>;
-using pwstring = pstring_t<pwchar_traits>;
+typedef pstring_t<putf8_traits> pstring;
+typedef pstring_t<putf16_traits> pu16string;
+typedef pstring_t<pwchar_traits> pwstring;
namespace plib
{
- template<class T>
- struct string_info
- {
- using mem_t = typename T::mem_t;
- };
-
- template<>
- struct string_info<std::string>
- {
- using mem_t = char;
- };
-
template<typename T>
pstring to_string(const T &v)
{
- return pstring(std::to_string(v));
+ return pstring(std::to_string(v), pstring::UTF8);
}
template<typename T>
pwstring to_wstring(const T &v)
{
- return pwstring(std::to_wstring(v));
- }
-
- template <typename T, typename E = void>
- struct pstonum_helper;
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value
- && std::is_signed<T>::value>::type>
- {
- template <typename S>
- long long operator()(const S &arg, std::size_t *idx)
- {
- return std::stoll(arg, idx);
- }
- };
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value
- && !std::is_signed<T>::value>::type>
- {
- template <typename S>
- unsigned long long operator()(const S &arg, std::size_t *idx)
- {
- return std::stoull(arg, idx);
- }
- };
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
- {
- template <typename S>
- long double operator()(const S &arg, std::size_t *idx)
- {
- return std::stold(arg, idx);
- }
- };
-
- template<typename T, typename S>
- T pstonum(const S &arg)
- {
- decltype(arg.c_str()) cstr = arg.c_str();
- std::size_t idx(0);
- auto ret = pstonum_helper<T>()(cstr, &idx);
- using ret_type = decltype(ret);
- if (ret >= static_cast<ret_type>(std::numeric_limits<T>::lowest())
- && ret <= static_cast<ret_type>(std::numeric_limits<T>::max()))
- //&& (ret == T(0) || std::abs(ret) >= std::numeric_limits<T>::min() ))
- {
- if (cstr[idx] != 0)
- throw std::invalid_argument(std::string("Continuation after numeric value ends: ") + cstr);
- }
- else
- {
- throw std::out_of_range(std::string("Out of range: ") + cstr);
- }
- return static_cast<T>(ret);
- }
-
- template<typename R, typename T>
- R pstonum_ne(const T &str, bool &err) noexcept
- {
- try
- {
- err = false;
- return pstonum<R>(str);
- }
- catch (...)
- {
- err = true;
- return R(0);
- }
- }
-
- template<typename T>
- typename T::size_type find_first_not_of(const T &str, const T &no)
- {
- typename T::size_type pos = 0;
- for (auto it = str.begin(); it != str.end(); ++it, ++pos)
- {
- bool f = true;
- for (typename T::value_type const jt : no)
- {
- if (*it == jt)
- {
- f = false;
- break;
- }
- }
- if (f)
- return pos;
- }
- return T::npos;
- }
-
- template<typename T>
- typename T::size_type find_last_not_of(const T &str, const T &no)
- {
- /* FIXME: reverse iterator */
- typename T::size_type last_found = T::npos;
- typename T::size_type pos = 0;
- for (auto it = str.begin(); it != str.end(); ++it, ++pos)
- {
- bool f = true;
- for (typename T::value_type const jt : no)
- {
- if (*it == jt)
- {
- f = false;
- break;
- }
- }
- if (f)
- last_found = pos;
- }
- return last_found;
- }
-
- template<typename T>
- T ltrim(const T &str, const T &ws = T(" \t\n\r"))
- {
- auto f = find_first_not_of(str, ws);
- return (f == T::npos) ? T() : str.substr(f);
+ return pwstring(std::to_wstring(v), pwstring::UTF16);
}
-
- template<typename T>
- T rtrim(const T &str, const T &ws = T(" \t\n\r"))
- {
- auto f = find_last_not_of(str, ws);
- return (f == T::npos) ? T() : str.substr(0, f + 1);
- }
-
- template<typename T>
- T trim(const T &str, const T &ws = T(" \t\n\r"))
- {
- return rtrim(ltrim(str, ws), ws);
- }
-
- template<typename T>
- T left(const T &str, typename T::size_type len)
- {
- return str.substr(0, len);
- }
-
- template<typename T>
- T right(const T &str, typename T::size_type nlen)
- {
- return nlen >= str.length() ? str : str.substr(str.length() - nlen, nlen);
- }
-
- template<typename T>
- bool startsWith(const T &str, const T &arg)
- {
- return (arg == left(str, arg.length()));
- }
-
- template<typename T>
- bool endsWith(const T &str, const T &arg)
- {
- return (right(str, arg.length()) == arg);
- }
-
- template<typename T>
- bool startsWith(const T &str, const char *arg)
- {
- return (left(str, std::strlen(arg)) == arg);
- }
-
- template<typename T>
- bool endsWith(const T &str, const char *arg)
- {
- return (right(str, std::strlen(arg)) == arg);
- }
-
- template<typename T>
- T ucase(const T &str)
- {
- T ret;
- for (const auto &c : str)
- if (c >= 'a' && c <= 'z')
- ret += (c - 'a' + 'A');
- else
- ret += c;
- return ret;
- }
-
- template<typename T>
- T rpad(const T &str, const T &ws, const typename T::size_type cnt)
- {
- // FIXME: pstringbuffer ret(*this);
-
- T ret(str);
- typename T::size_type wsl = ws.length();
- for (auto i = ret.length(); i < cnt; i+=wsl)
- ret += ws;
- return ret;
- }
-
- template<typename T>
- T replace_all(const T &str, const T &search, const T &replace)
- {
- T ret;
- const typename T::size_type slen = search.length();
-
- typename T::size_type last_s = 0;
- typename T::size_type s = str.find(search, last_s);
- while (s != T::npos)
- {
- ret += str.substr(last_s, s - last_s);
- ret += replace;
- last_s = s + slen;
- s = str.find(search, last_s);
- }
- ret += str.substr(last_s);
- return ret;
- }
-
- template<typename T, typename T1, typename T2>
- T replace_all(const T &str, const T1 &search, const T2 &replace)
- {
- return replace_all(str, static_cast<T>(search), static_cast<T>(replace));
- }
-
-} // namespace plib
+}
// custom specialization of std::hash can be injected in namespace std
namespace std
{
-
template<typename T> struct hash<pstring_t<T>>
{
- using argument_type = pstring_t<T>;
- using result_type = std::size_t;
+ typedef pstring_t<T> argument_type;
+ typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
- const typename argument_type::mem_t *string = s.c_str();
+ const pstring::mem_t *string = s.c_str();
result_type result = 5381;
- for (typename argument_type::mem_t c = *string; c != 0; c = *string++)
+ for (pstring::mem_t c = *string; c != 0; c = *string++)
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c);
return result;
}
};
-} // namespace std
+}
#endif /* PSTRING_H_ */
diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h
deleted file mode 100644
index 32ccc4f7b0d..00000000000
--- a/src/lib/netlist/plib/ptime.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * ptime.h
- */
-
-#ifndef PTIME_H_
-#define PTIME_H_
-
-#include "pconfig.h"
-#include "ptypes.h"
-
-#include <cstdint>
-
-// ----------------------------------------------------------------------------------------
-// netlist_time
-// ----------------------------------------------------------------------------------------
-
-namespace plib
-{
-
- template <typename TYPE, TYPE RES>
- struct ptime final
- {
- public:
-
- using internal_type = TYPE;
- using mult_type = TYPE;
-
- constexpr ptime() noexcept : m_time(0) {}
-
- ~ptime() noexcept = default;
-
- constexpr ptime(const ptime &rhs) noexcept = default;
- constexpr ptime(ptime &&rhs) noexcept = default;
- constexpr explicit ptime(const internal_type &time) noexcept : m_time(time) {}
- constexpr explicit ptime(internal_type &&time) noexcept : m_time(time) {}
- C14CONSTEXPR ptime &operator=(const ptime &rhs) noexcept = default;
- C14CONSTEXPR ptime &operator=(ptime &&rhs) noexcept = default;
-
- constexpr explicit ptime(const double t) = delete;
- //: m_time((internal_type) ( t * (double) resolution)) { }
- constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept
- : m_time(nom * (RES / den)) { }
-
- C14CONSTEXPR ptime &operator+=(const ptime rhs) noexcept { m_time += rhs.m_time; return *this; }
- C14CONSTEXPR ptime &operator-=(const ptime rhs) noexcept { m_time -= rhs.m_time; return *this; }
- C14CONSTEXPR ptime &operator*=(const mult_type factor) noexcept { m_time *= static_cast<internal_type>(factor); return *this; }
-
- friend constexpr const ptime operator-(ptime lhs, const ptime rhs) noexcept
- {
- return ptime(lhs.m_time - rhs.m_time);
- }
-
- friend constexpr const ptime operator+(ptime lhs, const ptime rhs) noexcept
- {
- return ptime(lhs.m_time + rhs.m_time);
- }
-
- friend constexpr const ptime operator*(ptime lhs, const mult_type &factor) noexcept
- {
- return ptime(lhs.m_time * factor);
- }
-
- friend constexpr mult_type operator/(const ptime lhs, const ptime rhs) noexcept
- {
- return static_cast<mult_type>(lhs.m_time / rhs.m_time);
- }
-
- friend constexpr bool operator<(const ptime lhs, const ptime rhs) noexcept
- {
- return (lhs.m_time < rhs.m_time);
- }
-
- friend constexpr bool operator>(const ptime lhs, const ptime rhs) noexcept
- {
- return (rhs < lhs);
- }
-
- friend constexpr bool operator<=(const ptime lhs, const ptime rhs) noexcept
- {
- return !(lhs > rhs);
- }
-
- friend constexpr bool operator>=(const ptime lhs, const ptime rhs) noexcept
- {
- return !(lhs < rhs);
- }
-
- friend constexpr bool operator==(const ptime lhs, const ptime rhs) noexcept
- {
- return lhs.m_time == rhs.m_time;
- }
-
- friend constexpr bool operator!=(const ptime lhs, const ptime rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- constexpr internal_type as_raw() const noexcept { return m_time; }
- constexpr double as_double() const noexcept
- {
- return static_cast<double>(m_time) * inv_res;
- }
-
- // for save states ....
- C14CONSTEXPR internal_type *get_internaltype_ptr() noexcept { return &m_time; }
-
- static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); }
- static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C( 1000000)); }
- static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C( 1000)); }
- static constexpr ptime from_sec(const internal_type s) noexcept { return ptime(s, UINT64_C( 1)); }
- static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); }
- static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); }
- static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(RES)), RES); }
-
- static constexpr ptime zero() noexcept { return ptime(0, RES); }
- static constexpr ptime quantum() noexcept { return ptime(1, RES); }
- static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), RES); }
- static constexpr internal_type resolution() noexcept { return RES; }
-
- constexpr internal_type in_nsec() const noexcept { return m_time / (RES / UINT64_C(1000000000)); }
- constexpr internal_type in_usec() const noexcept { return m_time / (RES / UINT64_C( 1000000)); }
- constexpr internal_type in_msec() const noexcept { return m_time / (RES / UINT64_C( 1000)); }
- constexpr internal_type in_sec() const noexcept { return m_time / (RES / UINT64_C( 1)); }
-
- private:
- static constexpr const double inv_res = 1.0 / static_cast<double>(RES);
- internal_type m_time;
- };
-
-
-} // namespace plib
-
-
-#endif /* PTIME_H_ */
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index bda62099150..0934a86fdf2 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -9,20 +9,10 @@
#define PTYPES_H_
#include "pconfig.h"
+#include "pstring.h"
-#include <limits>
-#include <string>
#include <type_traits>
-
-#define COPYASSIGNMOVE(name, def) \
- name(const name &) = def; \
- name(name &&) noexcept = def; \
- name &operator=(const name &) = def; \
- name &operator=(name &&) noexcept = def;
-
-#define COPYASSIGN(name, def) \
- name(const name &) = def; \
- name &operator=(const name &) = def; \
+#include <limits>
namespace plib
{
@@ -35,14 +25,14 @@ namespace plib
template<> struct is_integral<INT128> { static constexpr bool value = true; };
template<> struct numeric_limits<UINT128>
{
- static constexpr UINT128 max()
+ static inline constexpr UINT128 max()
{
return ~((UINT128)0);
}
};
template<> struct numeric_limits<INT128>
{
- static constexpr INT128 max()
+ static inline constexpr INT128 max()
{
return (~((UINT128)0)) >> 1;
}
@@ -55,98 +45,56 @@ namespace plib
struct nocopyassignmove
{
+ protected:
+ nocopyassignmove() = default;
+ ~nocopyassignmove() = default;
+ private:
nocopyassignmove(const nocopyassignmove &) = delete;
nocopyassignmove(nocopyassignmove &&) = delete;
nocopyassignmove &operator=(const nocopyassignmove &) = delete;
nocopyassignmove &operator=(nocopyassignmove &&) = delete;
- protected:
- nocopyassignmove() = default;
- ~nocopyassignmove() = default;
};
struct nocopyassign
{
- nocopyassign(const nocopyassign &) = delete;
- nocopyassign &operator=(const nocopyassign &) = delete;
protected:
nocopyassign() = default;
~nocopyassign() = default;
- nocopyassign(nocopyassign &&) = default;
- nocopyassign &operator=(nocopyassign &&) = default;
+ private:
+ nocopyassign(const nocopyassign &) = delete;
+ nocopyassign &operator=(const nocopyassign &) = delete;
};
//============================================================
- // Avoid unused variable warnings
+ // penum - strongly typed enumeration
//============================================================
- template<typename... Ts>
- inline void unused_var(Ts&&...) {}
- //============================================================
- // is_pow2
- //============================================================
- template <typename T>
- constexpr bool is_pow2(T v) noexcept
+ struct penum_base
{
- static_assert(is_integral<T>::value, "is_pow2 needs integer arguments");
- return !(v & (v-1));
- }
-
-
- //============================================================
- // abs, lcd, gcm
- //============================================================
-
- template<typename T>
- constexpr
- typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, T>::type
- abs(T v)
- {
- return v < 0 ? -v : v;
- }
-
- template<typename T>
- constexpr
- typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, T>::type
- abs(T v)
- {
- return v;
- }
-
- template<typename M, typename N>
- constexpr typename std::common_type<M, N>::type
- gcd(M m, N n)
- {
- static_assert(std::is_integral<M>::value, "gcd: M must be an integer");
- static_assert(std::is_integral<N>::value, "gcd: N must be an integer");
-
- return m == 0 ? plib::abs(n)
- : n == 0 ? plib::abs(m)
- : gcd(n, m % n);
- }
-
- template<typename M, typename N>
- constexpr typename std::common_type<M, N>::type
- lcm(M m, N n)
- {
- static_assert(std::is_integral<M>::value, "lcm: M must be an integer");
- static_assert(std::is_integral<N>::value, "lcm: N must be an integer");
-
- return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n) : 0;
- }
-
-} // namespace plib
+ protected:
+ static int from_string_int(const char *str, const char *x);
+ static pstring nthstr(int n, const char *str);
+ };
-//============================================================
-// Define a "has member" trait.
-//============================================================
+}
+
+#define P_ENUM(ename, ...) \
+ struct ename : public plib::penum_base { \
+ enum E { __VA_ARGS__ }; \
+ ename (E v) : m_v(v) { } \
+ bool set_from_string (const pstring &s) { \
+ static char const *const strings = # __VA_ARGS__; \
+ int f = from_string_int(strings, s.c_str()); \
+ if (f>=0) { m_v = static_cast<E>(f); return true; } else { return false; } \
+ } \
+ operator E() const {return m_v;} \
+ bool operator==(const ename &rhs) const {return m_v == rhs.m_v;} \
+ bool operator==(const E &rhs) const {return m_v == rhs;} \
+ const pstring name() const { \
+ static char const *const strings = # __VA_ARGS__; \
+ return nthstr(static_cast<int>(m_v), strings); \
+ } \
+ private: E m_v; };
-#define PDEFINE_HAS_MEMBER(name, member) \
- template <typename T> class name \
- { \
- template <typename U> static long test(decltype(&U:: member)); \
- template <typename U> static char test(...); \
- public: \
- static constexpr const bool value = sizeof(test<T>(nullptr)) == sizeof(long); \
- }
#endif /* PTYPES_H_ */
diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp
index b62cbf60865..c34102417ec 100644
--- a/src/lib/netlist/plib/putil.cpp
+++ b/src/lib/netlist/plib/putil.cpp
@@ -2,13 +2,13 @@
// copyright-holders:Couriersud
#include "putil.h"
-#include "plists.h"
#include "ptypes.h"
+#include "plists.h"
-#include <algorithm>
#include <cstdlib>
-#include <cstring>
+#include <algorithm>
#include <initializer_list>
+#include <cstring>
namespace plib
{
@@ -17,7 +17,7 @@ namespace plib
const pstring buildpath(std::initializer_list<pstring> list )
{
pstring ret = "";
- for( const auto &elem : list )
+ for( auto elem : list )
{
if (ret == "")
ret = elem;
@@ -33,12 +33,12 @@ namespace plib
const pstring environment(const pstring &var, const pstring &default_val)
{
- if (std::getenv(var.c_str()) == nullptr)
+ if (getenv(var.c_str()) == nullptr)
return default_val;
else
- return pstring(std::getenv(var.c_str()));
+ return pstring(getenv(var.c_str()), pstring::UTF8);
}
- } // namespace util
+ }
std::vector<pstring> psplit(const pstring &str, const pstring &onstr, bool ignore_empty)
{
@@ -64,36 +64,6 @@ namespace plib
return ret;
}
- std::vector<std::string> psplit_r(const std::string &stri,
- const std::string &token,
- const std::size_t maxsplit)
- {
- std::string str(stri);
- std::vector<std::string> result;
- std::size_t splits = 0;
-
- while(str.size())
- {
- std::size_t index = str.rfind(token);
- bool found = index!=std::string::npos;
- if (found)
- splits++;
- if ((splits <= maxsplit || maxsplit == 0) && found)
- {
- result.push_back(str.substr(index+token.size()));
- str = str.substr(0, index);
- if (str.size()==0)
- result.push_back(str);
- }
- else
- {
- result.push_back(str);
- str = "";
- }
- }
- return result;
- }
-
std::vector<pstring> psplit(const pstring &str, const std::vector<pstring> &onstrl)
{
pstring col = "";
@@ -102,7 +72,7 @@ namespace plib
auto i = str.begin();
while (i != str.end())
{
- auto p = static_cast<std::size_t>(-1);
+ std::size_t p = static_cast<std::size_t>(-1);
for (std::size_t j=0; j < onstrl.size(); j++)
{
if (std::equal(onstrl[j].begin(), onstrl[j].end(), i))
@@ -122,7 +92,7 @@ namespace plib
}
else
{
- pstring::value_type c = *i;
+ pstring::code_t c = *i;
col += c;
i++;
}
@@ -161,8 +131,31 @@ namespace plib
return cnt;
return -1;
}
- std::string penum_base::nthstr(int n, const char *str)
+ pstring penum_base::nthstr(int n, const char *str)
{
- return psplit(str, ",", false)[static_cast<std::size_t>(n)];
+ char buf[64];
+ char *bufp = buf;
+ int cur = 0;
+ while (*str)
+ {
+ if (cur == n)
+ {
+ if (*str == ',')
+ {
+ *bufp = 0;
+ return pstring(buf, pstring::UTF8);
+ }
+ else if (*str != ' ')
+ *bufp++ = *str;
+ }
+ else
+ {
+ if (*str == ',')
+ cur++;
+ }
+ str++;
+ }
+ *bufp = 0;
+ return pstring(buf, pstring::UTF8);
}
} // namespace plib
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index e8145361d9d..8d59c0357e2 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -5,32 +5,27 @@
*
*/
-#ifndef PUTIL_H_
-#define PUTIL_H_
+#ifndef P_UTIL_H_
+#define P_UTIL_H_
#include "pstring.h"
-#include <algorithm>
#include <initializer_list>
-#include <vector>
-
-#define PSTRINGIFY_HELP(y) # y
-#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
-
+#include <algorithm>
+#include <vector> // <<= needed by windows build
namespace plib
{
-
namespace util
{
const pstring buildpath(std::initializer_list<pstring> list );
const pstring environment(const pstring &var, const pstring &default_val);
- } // namespace util
+ }
namespace container
{
- template <class C, class T>
- bool contains(C &con, const T &elem)
+ template <class C>
+ bool contains(C &con, const typename C::value_type &elem)
{
return std::find(con.begin(), con.end(), elem) != con.end();
}
@@ -56,51 +51,7 @@ namespace plib
{
con.erase(std::remove(con.begin(), con.end(), elem), con.end());
}
- } // namespace container
-
- /* May be further specialized .... This is the generic version */
- template <typename T>
- struct constants
- {
- static constexpr T zero() noexcept { return static_cast<T>(0); }
- static constexpr T one() noexcept { return static_cast<T>(1); }
- static constexpr T two() noexcept { return static_cast<T>(2); }
-
- /*!
- * \brief Electric constant of vacuum
- */
- static constexpr T eps_0() noexcept { return static_cast<T>(8.854187817e-12); }
- /*!
- * \brief Relative permittivity of Silicon dioxide
- */
- static constexpr T eps_SiO2() noexcept { return static_cast<T>(3.9); }
- /*!
- * \brief Relative permittivity of Silicon
- */
- static constexpr T eps_Si() noexcept { return static_cast<T>(11.7); }
- /*!
- * \brief Boltzmann constant
- */
- static constexpr T k_b() noexcept { return static_cast<T>(1.38064852e-23); }
- /*!
- * \brief room temperature (gives VT = 0.02585 at T=300)
- */
- static constexpr T T0() noexcept { return static_cast<T>(300); }
- /*!
- * \brief Elementary charge
- */
- static constexpr T Q_e() noexcept { return static_cast<T>(1.6021765314e-19); }
- /*!
- * \brief Intrinsic carrier concentration in 1/m^3 of Silicon
- */
- static constexpr T NiSi() noexcept { return static_cast<T>(1.45e16); }
-
- template <typename V>
- static constexpr const T cast(V &&v) noexcept { return static_cast<T>(v); }
- };
-
- static_assert(noexcept(constants<double>::one()) == true, "Not evaluated as constexpr");
-
+ }
template <class C>
struct indexed_compare
@@ -118,41 +69,7 @@ namespace plib
std::vector<pstring> psplit(const pstring &str, const pstring &onstr, bool ignore_empty = false);
std::vector<pstring> psplit(const pstring &str, const std::vector<pstring> &onstrl);
- std::vector<std::string> psplit_r(const std::string &stri,
- const std::string &token,
- const std::size_t maxsplit);
-
-
- //============================================================
- // penum - strongly typed enumeration
- //============================================================
-
- struct penum_base
- {
- protected:
- static int from_string_int(const char *str, const char *x);
- static std::string nthstr(int n, const char *str);
- };
-
-} // namespace plib
-
-#define P_ENUM(ename, ...) \
- struct ename : public plib::penum_base { \
- enum E { __VA_ARGS__ }; \
- ename (E v) : m_v(v) { } \
- bool set_from_string (const std::string &s) { \
- static char const *const strings = # __VA_ARGS__; \
- int f = from_string_int(strings, s.c_str()); \
- if (f>=0) { m_v = static_cast<E>(f); return true; } else { return false; } \
- } \
- operator E() const {return m_v;} \
- bool operator==(const ename &rhs) const {return m_v == rhs.m_v;} \
- bool operator==(const E &rhs) const {return m_v == rhs;} \
- std::string name() const { \
- static char const *const strings = # __VA_ARGS__; \
- return nthstr(static_cast<int>(m_v), strings); \
- } \
- private: E m_v; };
+}
-#endif /* PUTIL_H_ */
+#endif /* P_UTIL_H_ */
diff --git a/src/lib/netlist/plib/vector_ops.h b/src/lib/netlist/plib/vector_ops.h
deleted file mode 100644
index 8043c48f61c..00000000000
--- a/src/lib/netlist/plib/vector_ops.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * vector_ops.h
- *
- * Base vector operations
- *
- */
-
-#ifndef PLIB_VECTOR_OPS_H_
-#define PLIB_VECTOR_OPS_H_
-
-#include "pconfig.h"
-
-#include <algorithm>
-#include <cmath>
-#include <type_traits>
-
-#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
-#if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3))
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
-#endif
-
-namespace plib
-{
- template<typename VT, typename T>
- void vec_set_scalar(const std::size_t n, VT &v, T && scalar)
- {
- const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
- for ( std::size_t i = 0; i < n; i++ )
- v[i] = s;
- }
-
- template<typename VT, typename VS>
- void vec_set(const std::size_t n, VT &v, const VS & source)
- {
- for ( std::size_t i = 0; i < n; i++ )
- v[i] = source[i];
- }
-
- template<typename T, typename V1, typename V2>
- T vec_mult(const std::size_t n, const V1 & v1, const V2 & v2 )
- {
- using b8 = T[8];
- PALIGNAS_VECTOROPT() b8 value = {0};
- for (std::size_t i = 0; i < n ; i++ )
- {
- value[i & 7] += v1[i] * v2[i];
- }
- return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7];
- }
-
- template<typename T, typename VT>
- T vec_mult2(const std::size_t n, const VT &v)
- {
- using b8 = T[8];
- PALIGNAS_VECTOROPT() b8 value = {0};
- for (std::size_t i = 0; i < n ; i++ )
- {
- value[i & 7] += v[i] * v[i];
- }
- return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7];
- }
-
- template<typename T, typename VT>
- T vec_sum(const std::size_t n, const VT &v)
- {
- if (n<8)
- {
- T value(0);
- for (std::size_t i = 0; i < n ; i++ )
- value += v[i];
-
- return value;
- }
- else
- {
- using b8 = T[8];
- PALIGNAS_VECTOROPT() b8 value = {0};
- for (std::size_t i = 0; i < n ; i++ )
- value[i & 7] += v[i];
-
- return ((value[0] + value[1]) + (value[2] + value[3])) + ((value[4] + value[5]) + (value[6] + value[7]));
- }
- }
-
- template<typename VV, typename T, typename VR>
- void vec_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
- {
- const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
- for ( std::size_t i = 0; i < n; i++ )
- result[i] = s * v[i];
- }
-
- template<typename VR, typename VV, typename T>
- void vec_add_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
- {
- const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
- for ( std::size_t i = 0; i < n; i++ )
- result[i] += s * v[i];
- }
-
- template<typename T>
- void vec_add_mult_scalar_p(const std::size_t n, T * result, const T * v, T scalar)
- {
- for ( std::size_t i = 0; i < n; i++ )
- result[i] += scalar * v[i];
- }
-
- template<typename R, typename V>
- void vec_add_ip(const std::size_t n, R & result, const V & v)
- {
- for ( std::size_t i = 0; i < n; i++ )
- result[i] += v[i];
- }
-
- template<typename VR, typename V1, typename V2>
- void vec_sub(const std::size_t n, VR & result, const V1 &v1, const V2 & v2)
- {
- for ( std::size_t i = 0; i < n; i++ )
- result[i] = v1[i] - v2[i];
- }
-
- template<typename V, typename T>
- void vec_scale(const std::size_t n, V & v, T &&scalar)
- {
- const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
- for ( std::size_t i = 0; i < n; i++ )
- v[i] *= s;
- }
-
- template<typename T, typename V>
- T vec_maxabs(const std::size_t n, const V & v)
- {
- T ret = 0.0;
- for ( std::size_t i = 0; i < n; i++ )
- ret = std::max(ret, std::abs(v[i]));
-
- return ret;
- }
-} // namespace plib
-
-#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
-#if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3))
-#pragma GCC diagnostic pop
-#endif
-#endif
-
-#endif /* PLIB_VECTOR_OPS_H_ */