diff options
Diffstat (limited to 'src/lib/netlist/tests')
-rw-r--r-- | src/lib/netlist/tests/test_penum.cpp | 254 | ||||
-rw-r--r-- | src/lib/netlist/tests/test_pfunction.cpp | 60 | ||||
-rw-r--r-- | src/lib/netlist/tests/test_pmfp.cpp | 77 | ||||
-rw-r--r-- | src/lib/netlist/tests/test_pmfp_multibase.cpp | 451 | ||||
-rw-r--r-- | src/lib/netlist/tests/test_precommit.cpp | 27 | ||||
-rw-r--r-- | src/lib/netlist/tests/test_pstring.cpp | 19 |
6 files changed, 888 insertions, 0 deletions
diff --git a/src/lib/netlist/tests/test_penum.cpp b/src/lib/netlist/tests/test_penum.cpp new file mode 100644 index 00000000000..6347a41d027 --- /dev/null +++ b/src/lib/netlist/tests/test_penum.cpp @@ -0,0 +1,254 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_penum.cpp +/// +/// tests for penum +/// + +#include "plib/putil.h" + +#include "plib/pexception.h" +#include "plib/pstring.h" + +#include <string> +#include <type_traits> +#include <string_view> + +#if 0 +namespace plib +{ + template <typename E> + struct functor { using is_defined = std::false_type; }; + template <std::size_t N, typename E> + struct functor_base + { + public: + using is_defined = std::true_type; + using size = std::integral_constant<std::size_t, N>; + constexpr operator E () const noexcept { return m_v; } + constexpr functor_base(const E v) noexcept : m_v(v) { }; + protected: + constexpr functor_base(const char *s, const char * const vals[size::value]) noexcept : m_v(E::PENUM_UNKNOWN) + { for (std::size_t i = 0; i < size::value; i++) if (vals[i] == s) { m_v = static_cast<E>(i); return; } } + E m_v; + private: + //static constexpr const char *m_str[PNARGS(__VA_ARGS__)] = { PSTRINGIFY_VA(__VA_ARGS__) }; + }; + +} // namespace plib + +#define PENUM(ename, ...) \ + enum class ename { __VA_ARGS__ , PENUM_UNKNOWN }; \ + PENUM_FUNCTOR(ename, __VA_ARGS__) + +#define PENUM_NS(ns, ename, ...) \ + namespace ns { enum class ename { __VA_ARGS__ , PENUM_UNKNOWN }; } \ + PENUM_FUNCTOR(ns :: ename, __VA_ARGS__) + +#define PENUM_FUNCTOR(ename, ...) \ + template <> struct plib::functor<ename> : plib::functor_base<PNARGS(__VA_ARGS__), ename> \ + { \ + public: \ + using plib::functor_base<size::value, ename>::functor_base; \ + constexpr functor(const char *s) noexcept : functor_base(s, m_str) { } \ + constexpr operator const char * () const noexcept { return m_str[static_cast<std::size_t>(m_v)]; } \ + private: \ + static constexpr const char *m_str[3] = { PSTRINGIFY_VA(__VA_ARGS__) }; \ + }; + +#else +#if 1 +namespace plib::enum_static +{ + template <typename E> + struct functor_static + { + using is_defined = std::false_type; + using size = std::integral_constant<std::size_t, 0>; + static constexpr const char *m_str[1] = { "" }; + }; +} // namespace plib::enum_static + +#endif +namespace plib +{ + template <typename E> + struct functor + { + public: + using staticf = enum_static::functor_static<E>; + using is_defined = typename staticf::is_defined; + using size = typename staticf::size; + constexpr functor(const E v) noexcept : m_v(v) { } + constexpr functor(const char *s) noexcept : m_v(E::PENUM_UNKNOWN) + { + for (std::size_t i = 0; i < size::value; i++) + if (staticf::m_str[i] == s) + { + m_v = static_cast<E>(i); + return; + } + } + constexpr operator const char * () const noexcept { return staticf::m_str[static_cast<std::size_t>(m_v)]; } + constexpr operator E () const noexcept { return m_v; } + protected: + E m_v; + private: + //static constexpr const char *m_str[PNARGS(__VA_ARGS__)] = { PSTRINGIFY_VA(__VA_ARGS__) }; + }; + + // template deduction guide + template<typename E> functor(E) -> functor<E>; + + template<typename E> + static inline typename std::enable_if<plib::enum_static::functor_static<E>::is_defined::value, const char *>::type + penum_to_string(E e) + { + using staticf = enum_static::functor_static<E>; + return staticf::m_str[static_cast<std::size_t>(e)]; + } + + template<typename E> + static inline typename std::enable_if<plib::enum_static::functor_static<E>::is_defined::value, E>::type + string_to_penum(const char *s) + { + using staticf = enum_static::functor_static<E>; + for (std::size_t i = 0; i < staticf::size::value; i++) + if (staticf::m_str[i] == s) + return static_cast<E>(i); + return E::PENUM_UNKNOWN; + } + +} // namespace plib + +#define PENUM(ename, ...) \ + enum class ename { __VA_ARGS__ , PENUM_UNKNOWN }; \ + PENUM_FUNCTOR(ename, __VA_ARGS__) + +#define PENUM_NS(ns, ename, ...) \ + namespace ns { enum class ename { __VA_ARGS__ , PENUM_UNKNOWN }; } \ + PENUM_FUNCTOR(ns :: ename, __VA_ARGS__) + +#define PENUM_FUNCTOR(ename, ...) \ + namespace plib::enum_static { \ + template <> struct functor_static<ename> \ + { \ + public: \ + using is_defined = std::true_type; \ + using size = std::integral_constant<std::size_t, PNARGS(__VA_ARGS__) >; \ + static constexpr const char *m_str[size::value] = { PSTRINGIFY_VA(__VA_ARGS__) }; \ + }; \ + } // namespace plib::enum_static + +#endif + +template <class O, class E> +typename std::enable_if<!plib::has_ostream_operator<O, E>::value && plib::enum_static::functor_static<E>::is_defined::value, O&>::type +operator << (O& os, const E &p) +{ + os << static_cast<const char *>(plib::functor<E>(p)); + return os; +} + +#if 1 +template <typename E> +inline typename std::enable_if<plib::enum_static::functor_static<E>::is_defined::value, bool>::type +operator == (const char * lhs, const E &rhs) +{ + return lhs == plib::functor<E>(rhs); +} +template <typename E> +inline typename std::enable_if<plib::enum_static::functor_static<E>::is_defined::value, bool>::type +operator == (const E &lhs, const char * rhs) +{ + return lhs == plib::functor<E>(rhs); +} +#endif + +// --------------------------------------- + +template <typename T> +struct ret_t +{ + bool success; + T value; +}; + +template <typename T, T BASE> +constexpr ret_t<T> stl_h(std::string_view sv) +{ + T r(0); + for (const auto &c : sv) + { + if (c >= '0' && c < '0' + std::min(10,BASE)) + { + r = r * BASE + (c - '0'); + } + else if (c >= 'A' && c < ('A' + BASE - 10)) + { + r = r * BASE + (10 + c - 'A'); + } + else if (c >= 'a' && c < ('a' + BASE - 10)) + { + r = r * BASE + (10 + c - 'a'); + } + else + return { false, T(0) }; + } + return { true, r }; +} + +template <typename T, T BASE = 0> +constexpr ret_t<T> stl(std::string_view sv) +{ + if constexpr (BASE == 0) + { + if (sv.size() > 2) + { + if (sv.substr(0,2) == "0x" || sv.substr(0,2) == "0X") + return stl_h<T,16>(sv.substr(2)); + if (sv.substr(0,2) == "0b") + return stl_h<T,2>(sv.substr(2)); + } + if (sv.size() > 1 && sv.substr(0,1) == "0" ) + return stl_h<T,8>(sv.substr(1)); + return stl_h<T, 10>(sv); + } + return stl_h<T, BASE>(sv); +} + +#include "plib/ptests.h" + +//PENUM_NS(plibx, teste, A, B, C) + +namespace plibx { enum class teste; } +PENUM(plibx::teste, A, B, C) + +enum class pure { X, Y }; + +PENUM(testf, A, B, C) + +PTEST(penum, conversion) +{ + static_assert(stl<int,0>("0xa0bc").success,"no"); + static_assert(stl<int,0>("0xa0bc").value==0xa0bc,"no"); + static_assert(stl<int,0>("0b1010").value==0b1010,"no"); + static_assert(stl<int,0>("0123").value==0123,"no"); + //const auto x(stl<int,0>("123")); + //static_assert(x.value==123,"no"); + + plibx::teste x = plib::functor<plibx::teste>("A"); + PEXPECT_NE(x, plibx::teste::B); + PEXPECT_NE(plib::functor<plibx::teste>("A"), plibx::teste::B); + PEXPECT_NE(plib::functor<testf>("A"), testf::B); + //PEXPECT_EQ(plib::functor("A"), testf::B); + PEXPECT_EQ(testf::B, "B"); + PEXPECT_EQ("A", testf::A); + PEXPECT_NE(plib::functor(testf::A), "B"); + PEXPECT_FALSE(plib::functor<pure>::is_defined::value); + PEXPECT_EQ(plib::penum_to_string(testf::B), "B"); + PEXPECT_NE(plib::string_to_penum<testf>("B"), testf::A); + //PEXPECT_EQ(pure::X, pure::Y); +} diff --git a/src/lib/netlist/tests/test_pfunction.cpp b/src/lib/netlist/tests/test_pfunction.cpp new file mode 100644 index 00000000000..fa100e7edb2 --- /dev/null +++ b/src/lib/netlist/tests/test_pfunction.cpp @@ -0,0 +1,60 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_pfunction.cpp +/// +/// tests for `pfunction` class +/// + +#include "plib/ptests.h" + +#include "plib/pexception.h" +#include "plib/pfunction.h" + +#define PFUNCEXPECT(formula, val) \ + PEXPECT_EQ(val, plib::pfunction<double>(formula)()) + +PTEST(pfunction, operators) +{ + PFUNCEXPECT("1==1", 1.0); + PFUNCEXPECT("1 *0 == 2-1-1", 1.0); + PFUNCEXPECT("0!=1", 1.0); + PFUNCEXPECT("0<1", 1.0); + PFUNCEXPECT("1>0", 1.0); + PFUNCEXPECT("0<=1", 1.0); + PFUNCEXPECT("1>=0", 1.0); + PFUNCEXPECT("1<=1", 1.0); + PFUNCEXPECT("1>=1", 1.0); + PEXPECT_EQ(1.0, plib::pfunction<double>("0!=a", {"a"})({1.0})); +} + +PTEST(pfunction, func_if) +{ + PFUNCEXPECT("if(1>0, 2, 0)", 2.0); + PFUNCEXPECT("if(0>1, 2, 3)", 3.0); + PFUNCEXPECT("if(sin(1)>0, 2, 3)", 2.0); // fail + PEXPECT_EQ( 1.0, plib::pfunction<double>("if(A2>2.5, 0-A1, (0.07-(0.005*A1))*if(A0>2.5,1,0-1))", {"A0","A1","A2"})({1.0,-1.0,3.0})); + PEXPECT_EQ(-0.065, plib::pfunction<double>("if(A2>2.5, 0-A1, (0.07-(0.005*A1))*if(A0>2.5,1,0-1))", {"A0","A1","A2"})({1.0,1.0,1.0})); + PEXPECT_EQ( 0.065, plib::pfunction<double>("if(A2>2.5, 0-A1, (0.07-(0.005*A1))*if(A0>2.5,1,0-1))", {"A0","A1","A2"})({3.0,1.0,1.0})); + PEXPECT_TRUE(1.0 == plib::pfunction<double>("0!=a", {"a"})({1.0})); +} + +PTEST(pfunction, unary_minus) +{ + PFUNCEXPECT("-1>-2", 1.0); + PFUNCEXPECT("(-3)*(-4)", 12.0); + PFUNCEXPECT("(-3)*-4", 12.0); + PFUNCEXPECT("-3*-4", 12.0); + PEXPECT_EQ( -3.0, plib::pfunction<double>("-A0", {"A0"})({3.0})); + PFUNCEXPECT("3*-trunc(3.2)", -9.0); + PFUNCEXPECT("3*-(3*2)", -18.0); + PFUNCEXPECT("3*-(2*1)^2", -12.0); + PEXPECT_NO_THROW(plib::pfunction<double>("(-3)")()); // fail +} +PTEST(pfunction, expect_throw) +{ + PEXPECT_THROW(plib::pfunction<double>("(3, 4)")(), plib::pexception); + PEXPECT_THROW(plib::pfunction<double>("((3)")(), plib::pexception); + PEXPECT_THROW(plib::pfunction<double>("(3))")(), plib::pexception); +} diff --git a/src/lib/netlist/tests/test_pmfp.cpp b/src/lib/netlist/tests/test_pmfp.cpp new file mode 100644 index 00000000000..c6c9bf70daa --- /dev/null +++ b/src/lib/netlist/tests/test_pmfp.cpp @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_pmfp.cpp +/// +/// tests for `plib::pmfp` class +/// + +#include "plib/ptests.h" + +#include "plib/pexception.h" +#include "plib/ppmf.h" + +#include <memory> +#include <utility> + +/// `plib::late_pmfp<plib::pmfp<void, pstring>> a(&nld_7493::printer);` +/// // Store the a object somewhere +/// +/// // After full construction ... +/// +/// ``` +/// auto dele = a(this); +/// dele(pstring("Hello World!")); +/// ``` + +class test_late_pmfp : public plib::testing::Test +{ +protected: + class late_pmfp_object + { + public: + void ap(int &r) { r = ax; } + int ax; + }; + +}; + +PTEST_F(test_late_pmfp, late_pmfp) +{ +#if !PPMF_USE_MAME_DELEGATES + plib::late_pmfp<plib::pmfp<void (int &)>> late(&late_pmfp_object::ap); + + late_pmfp_object a; + a.ax = 1; + auto mfp(late(&a)); + int r(0); + mfp(r); + PEXPECT_TRUE(r == 1); +#endif +} + +PTEST(test_compile, compile) +{ +#if !PPMF_USE_MAME_DELEGATES + plib::pmfp_base<plib::ppmf_type::PMF, void(int)> mfp_PPMF_TYPE_PMF; + plib::pmfp_base<plib::ppmf_type::INTERNAL_ITANIUM, void(int)> mfp_PPMF_TYPE_INTERNAL_ITANIUM; + plib::pmfp_base<plib::ppmf_type::INTERNAL_ARM, void(int)> mfp_PPMF_TYPE_INTERNAL_ARM; + plib::pmfp_base<plib::ppmf_type::INTERNAL_MSC, void(int)> mfp_PPMF_TYPE_INTERNAL_MSC; + PEXPECT_TRUE(mfp_PPMF_TYPE_PMF.isnull()); + PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_ITANIUM.isnull()); + PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_ARM.isnull()); + PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_MSC.isnull()); +#endif + // FIXME: clang on linux seems to support GNUC_PMF_CONV - test needed + // Need to check for clang-cl here. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__NVCC__) + plib::pmfp_base<plib::ppmf_type::GNUC_PMF_CONV, void(int)> mfp_PPMF_TYPE_GNUC_PMF_CONV; + PEXPECT_TRUE(mfp_PPMF_TYPE_GNUC_PMF_CONV.isnull()); +#else + PEXPECT_NE("ppmf_type::GNUC_PMF_CONV not supported on this build", ""); +#endif +#if defined(__EMSCRIPTEN__) + PEXPECT_EQ(int(plib::ppmf_internal_selector::value), int(plib::ppmf_type::INTERNAL_ARM)); +#endif +} diff --git a/src/lib/netlist/tests/test_pmfp_multibase.cpp b/src/lib/netlist/tests/test_pmfp_multibase.cpp new file mode 100644 index 00000000000..8297792eae7 --- /dev/null +++ b/src/lib/netlist/tests/test_pmfp_multibase.cpp @@ -0,0 +1,451 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_pmfp_multibase.cpp +/// +/// tests for `plib::pmfp` +/// + +#include "plib/ptypes.h" +#include "plib/pexception.h" +#include "plib/ppmf.h" + +#include <iostream> +#include <memory> +#include <type_traits> +#include <typeinfo> +#include <utility> + +template <class F, class S> +typename std::enable_if_t<!plib::has_ostream_operator<std::basic_ostream<char>, std::pair<F, S>>::value, std::basic_ostream<char>&> +operator << (std::basic_ostream<char>& os, const std::pair<F, S> &p) +{ + os << "{ " << p.first << ", " << p.second << " }"; + return os; +} + +#include "plib/ptests.h" + +template <class T> +typename std::enable_if_t<!plib::has_ostream_operator<std::basic_ostream<char>, T>::value, std::basic_ostream<char>&> +operator << ([[maybe_unused]] std::basic_ostream<char>& os, [[maybe_unused]] const T &p) +{ + os << std::string(typeid(T).name()); + return os; +} + +class pmfp_test_complex_return : public plib::testing::Test +{ +protected: + using ret_t = std::pair<void *, int>; + + template <std::size_t N> + class tstruct + { + public: + struct r1type + { + char m[N]; + }; + + r1type f1(const char v) + { + r1type r; + for (std::size_t i=0; i<N; i++) r.m[i] = v; + return r; + } + + template <typename T> + T ft(const T v) + { + return v; + } + + template <typename T> + T run_ft(const T v) + { + using pf_t = plib::pmfp<T (const T)>; + pf_t pf(&tstruct::ft<T>, this); + return pf(v); + } + }; + + //using test_delegate1 = plib::pmfp<ret_t (int, int)>; + using test_delegate = plib::pmfp<ret_t ()>; + + class a + { + public: + ret_t ap() { return ret_t(static_cast<void *>(this), ax); } + int ax; + }; + + class b + { + public: + ret_t bp() { return ret_t(static_cast<void *>(this), bx); } + int bx; + }; + + class multibase : public a, public b + { + public: + }; + + + class vtb + { + public: + virtual ~vtb() = default; + virtual ret_t vp1() { return ret_t(static_cast<void *>(this), 1); } + virtual ret_t vp2() { return ret_t(static_cast<void *>(this), 2); } + }; + + class vti1 : public vtb + { + public: + virtual ret_t vp1() override { return ret_t(static_cast<void *>(this), 3); } + virtual ret_t vp2() override { return ret_t(static_cast<void *>(this), 4); } + }; + + class vti2 : public a, public vtb + { + public: + virtual ret_t vp1() override { return ret_t(static_cast<void *>(this), 13); } + virtual ret_t vp2() override { return ret_t(static_cast<void *>(this), 14); } + }; + + class forward; + + test_delegate make_forward_delegate(ret_t (forward::*func)(), forward *obj) + { + return test_delegate(func, obj); + } + + class vb + { + public: + ret_t xp() { return ret_t(static_cast<void *>(this), x); } + int x=10; + }; + + class vd1 : public virtual vb + { + public: + ret_t yp() { return ret_t(static_cast<void *>(this), y); } + int y; + }; + + class vd2 : public virtual vb + { + public: + ret_t zp() { return ret_t(static_cast<void *>(this), z); } + int z; + }; + + class forward : public vd1, public vd2 + { + public: + }; + +}; + +class pmfp_test_simple_return : public plib::testing::Test +{ +protected: + using ret_t = std::pair<void *, int>; + + //using test_delegate1 = plib::pmfp<ret_t (int, int)>; + using test_delegate = plib::pmfp<void (ret_t &)>; + + class a + { + public: + void ap(ret_t &r) { r = ret_t(static_cast<void *>(this), ax); } + int ax; + }; + + class b + { + public: + void bp(ret_t &r) { r = ret_t(static_cast<void *>(this), bx); } + int bx; + }; + + class multibase : public a, public b + { + public: + }; + + + class vtb + { + public: + virtual ~vtb() = default; + virtual void vp1(ret_t &r) { r = ret_t(static_cast<void *>(this), 1); } + virtual void vp2(ret_t &r) { r = ret_t(static_cast<void *>(this), 2); } + }; + + class vti1 : public vtb + { + public: + virtual void vp1(ret_t &r) override { r = ret_t(static_cast<void *>(this), 3); } + virtual void vp2(ret_t &r) override { r = ret_t(static_cast<void *>(this), 4); } + }; + + class vti2 : public a, public vtb + { + public: + virtual void vp1(ret_t &r) override { r = ret_t(static_cast<void *>(this), 13); } + virtual void vp2(ret_t &r) override { r = ret_t(static_cast<void *>(this), 14); } + }; + + class forward; + + test_delegate make_forward_delegate(void (forward::*func)(ret_t &), forward *obj) + { + return test_delegate(func, obj); + } + + class vb + { + public: + void xp(ret_t &r) { r = ret_t(static_cast<void *>(this), x); } + int x=10; + }; + + class vd1 : public virtual vb + { + public: + void yp(ret_t &r) { r = ret_t(static_cast<void *>(this), y); } + int y; + }; + + class vd2 : public virtual vb + { + public: + void zp(ret_t &r) { r = ret_t(static_cast<void *>(this), z); } + int z; + }; + + class forward : public vd1, public vd2 + { + public: + }; +}; + +PTEST_F(pmfp_test_complex_return, multibase_test) +{ + multibase obj; + obj.ax = 1; + obj.bx = 2; + test_delegate f(&multibase::ap, &obj); + test_delegate g(&multibase::bp, &obj); + + // a=0x63fbf8 + // b=0x63fbfc + // a=0x63fbf8(1) + // b=0x63fbfc(2) + // b=0x63fbfc(2) + // b=0x63fbfc(2) + PEXPECT_EQ(f(), ret_t(static_cast<void *>(static_cast<a *>(&obj)), 1)); + auto g_ret = g(); + PEXPECT_EQ(g_ret, ret_t(static_cast<void *>(static_cast<b *>(&obj)), 2)); + + test_delegate h = g; + PEXPECT_EQ(g_ret, h()); + f = g; + PEXPECT_EQ(g_ret, f()); + + //vti1=0xdf6fb0.vp1 + //vti1=0xdf6fb0.vp2 + + std::unique_ptr<vtb> ptr; + ptr.reset(new vti1); + f = test_delegate(&vtb::vp1, ptr.get()); + auto f1_ret = f(); + f = test_delegate(&vtb::vp2, ptr.get()); + auto f2_ret = f(); + PEXPECT_EQ(f1_ret.first, f2_ret.first); + PEXPECT_EQ(f1_ret.second, 3); + PEXPECT_EQ(f2_ret.second, 4); + + // vti2=0xdf6d50.vp1 + // vti2=0xdf6d50.vp2 + ptr.reset(new vti2); + f = test_delegate(&vtb::vp1, ptr.get()); + f1_ret = f(); + f = test_delegate(&vtb::vp2, ptr.get()); + f2_ret = f(); + PEXPECT_EQ(f1_ret.first, f2_ret.first); + PEXPECT_EQ(f1_ret.second, 13); + PEXPECT_EQ(f2_ret.second, 14); + + //vb=0x63fafc + //vd1=0x63fae0 + //vd2=0x63faf0 + //vd1=0x63fae0(8) + //vd2=0x63faf0(9) + + forward obj2; + obj2.x = 7; + obj2.y = 8; + obj2.z = 9; + PEXPECT_NE(static_cast<void *>(static_cast<vb *>(&obj2)), static_cast<void *>(static_cast<vd1 *>(&obj2))); + PEXPECT_NE(static_cast<void *>(static_cast<vb *>(&obj2)), static_cast<void *>(static_cast<vd2 *>(&obj2))); + +#if defined(_MSC_VER) && !defined(__clang__) + f = make_forward_delegate(&forward::xp, &obj2); + PEXPECT_TRUE(f().second == 7); + std::cout << f().second << " " << obj2.xp().second << "\n"; +#endif + f = make_forward_delegate(&forward::yp, &obj2); + PEXPECT_EQ(f().second, 8); + f = make_forward_delegate(&forward::zp, &obj2); + PEXPECT_EQ(f().second, 9); + //PEXPECT_EQ(plib::ppmf_internal::value, PPMF_TYPE_PMF); + + // test return size handling + + tstruct<3> ts3; + using pfmp3_t = plib::pmfp<tstruct<3>::r1type(char)>; + pfmp3_t pf3(&tstruct<3>::f1, &ts3); + auto r3 = pf3(3); + PEXPECT_EQ(static_cast<int>(r3.m[2]), 3); + PEXPECT_EQ(sizeof(r3), 3u); + + tstruct<5> ts5; + using pfmp5_t = plib::pmfp<tstruct<5>::r1type(char)>; + pfmp5_t pf5(&tstruct<5>::f1, &ts5); + auto r5 = pf5(5); + PEXPECT_EQ(static_cast<int>(r5.m[3]), 5); + PEXPECT_EQ(sizeof(r5), 5u); + + tstruct<8> ts8; + using pfmp8_t = plib::pmfp<tstruct<8>::r1type(char)>; + pfmp8_t pf8(&tstruct<8>::f1, &ts8); + auto r8 = pf8(8); + PEXPECT_EQ(static_cast<int>(r8.m[3]), 8); + PEXPECT_EQ(sizeof(r8), 8u); + + tstruct<9> ts9; + using pfmp9_t = plib::pmfp<tstruct<9>::r1type (char)>; + pfmp9_t pf9(&tstruct<9>::f1, &ts9); + auto r9=pf9(9); + PEXPECT_EQ(static_cast<int>(r9.m[3]), 9); + PEXPECT_EQ(sizeof(r9), 9u); + + tstruct<17> ts17; + using pfmp17_t = plib::pmfp<tstruct<17>::r1type(char)>; + pfmp17_t pf17(&tstruct<17>::f1, &ts17); + auto r17 = pf17(17); + PEXPECT_EQ(static_cast<int>(r17.m[3]), 17); + PEXPECT_EQ(sizeof(r17), 17u); + +#if !(defined(_MSC_VER) && !defined(__clang__)) + if constexpr (plib::compile_info::has_int128::value) + { + PEXPECT_EQ(static_cast<int>(ts17.run_ft<INT128>(17)), 17); // FIXME: no operator << for INT128 yet + PEXPECT_EQ(sizeof(INT128), 16u); + } +#endif + PEXPECT_EQ(ts17.run_ft<long double>(17), 17); + PEXPECT_EQ(ts17.run_ft<double>(17), 17); + PEXPECT_EQ(ts17.run_ft<int>(17), 17); + PEXPECT_EQ(ts17.run_ft<bool>(true), true); + PEXPECT_EQ(ts17.run_ft<std::size_t>(20), 20u); + + struct tt1_t { int a; int b; }; + tt1_t tt1 = { 8, 9 }; + auto tt1r = ts17.run_ft<tt1_t>(tt1); + PEXPECT_EQ(tt1.a, tt1r.a); + PEXPECT_EQ(tt1.b, tt1r.b); + + PEXPECT_EQ(sizeof(ret_t), 16u); + +} + +PTEST_F(pmfp_test_simple_return, multibase_test) +{ + multibase obj; + obj.ax = 1; + obj.bx = 2; + test_delegate f(&multibase::ap, &obj); + test_delegate g(&multibase::bp, &obj); + + // a=0x63fbf8 + // b=0x63fbfc + // a=0x63fbf8(1) + // b=0x63fbfc(2) + // b=0x63fbfc(2) + // b=0x63fbfc(2) + ret_t fr; + f(fr); + PEXPECT_EQ(fr, ret_t(static_cast<void *>(static_cast<a *>(&obj)), 1)); + ret_t gr; + g(gr); + PEXPECT_EQ(gr, ret_t(static_cast<void *>(static_cast<b *>(&obj)), 2)); + //PEXPECT_EQ(f, g); + + test_delegate h = g; + ret_t hr; + h(hr); + PEXPECT_EQ(gr, hr); + f = g; + f(fr); + PEXPECT_EQ(gr, fr); + + //vti1=0xdf6fb0.vp1 + //vti1=0xdf6fb0.vp2 + + std::unique_ptr<vtb> ptr; + ptr.reset(new vti1); + f = test_delegate(&vtb::vp1, ptr.get()); + ret_t f1_ret; + f(f1_ret); + f = test_delegate(&vtb::vp2, ptr.get()); + ret_t f2_ret; + f(f2_ret); + PEXPECT_EQ(f1_ret.first, f2_ret.first); + PEXPECT_EQ(f1_ret.second, 3); + PEXPECT_EQ(f2_ret.second, 4); + + // vti2=0xdf6d50.vp1 + // vti2=0xdf6d50.vp2 + ptr.reset(new vti2); + f = test_delegate(&vtb::vp1, ptr.get()); + f(f1_ret); + f = test_delegate(&vtb::vp2, ptr.get()); + f(f2_ret); + PEXPECT_EQ(f1_ret.first, f2_ret.first); + PEXPECT_EQ(f1_ret.second, 13); + PEXPECT_EQ(f2_ret.second, 14); + + //vb=0x63fafc + //vd1=0x63fae0 + //vd2=0x63faf0 + //vd1=0x63fae0(8) + //vd2=0x63faf0(9) + + forward obj2; + obj2.x = 7; + obj2.y = 8; + obj2.z = 9; + PEXPECT_NE(static_cast<void *>(static_cast<vb *>(&obj2)), static_cast<void *>(static_cast<vd1 *>(&obj2))); + PEXPECT_NE(static_cast<void *>(static_cast<vb *>(&obj2)), static_cast<void *>(static_cast<vd2 *>(&obj2))); + +#if defined(_MSC_VER) && !defined(__clang__) + f = make_forward_delegate(&forward::xp, &obj2); + f(fr); + PEXPECT_TRUE(fr.second == 7); + std::cout << fr.second << "\n"; +#endif + f = make_forward_delegate(&forward::yp, &obj2); + f(fr); + PEXPECT_EQ(fr.second, 8); + f = make_forward_delegate(&forward::zp, &obj2); + f(fr); + PEXPECT_EQ(fr.second, 9); + //PEXPECT_EQ(plib::ppmf_internal::value, PPMF_TYPE_INTERNAL_MSC); +} diff --git a/src/lib/netlist/tests/test_precommit.cpp b/src/lib/netlist/tests/test_precommit.cpp new file mode 100644 index 00000000000..6faf8029c0b --- /dev/null +++ b/src/lib/netlist/tests/test_precommit.cpp @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_precommit.cpp +/// +/// tests to check for experimental code before commit +/// + +#include "nl_config.h" + +#include "plib/pconfig.h" +#include "plib/ppmf.h" +#include "plib/ptests.h" + +PTEST(test_precommit, precommit) +{ + PEXPECT_EQ(PPMF_EXPERIMENTAL, 0); + PEXPECT_EQ(PPMF_USE_MAME_DELEGATES, 0); + + PEXPECT_EQ(netlist::config::use_copy_instead_of_reference::value, false); + PEXPECT_EQ(NL_USE_BACKWARD_EULER, 1); + PEXPECT_EQ(PUSE_FLOAT128, 0); + PEXPECT_EQ(NL_USE_FLOAT128, PUSE_FLOAT128); + PEXPECT_EQ(NL_USE_INPLACE_CORE_TERMS, 0); + PEXPECT_EQ(netlist::config::avoid_noop_queue_pushes::value, false); +} diff --git a/src/lib/netlist/tests/test_pstring.cpp b/src/lib/netlist/tests/test_pstring.cpp new file mode 100644 index 00000000000..3196e634ea6 --- /dev/null +++ b/src/lib/netlist/tests/test_pstring.cpp @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Couriersud + +/// +/// \file test_pstring.cpp +/// +/// tests for pstring +/// + +#include "plib/ptests.h" + +#include "plib/pexception.h" +#include "plib/pstring.h" + +PTEST(pstring, conversion) +{ + PEXPECT_EQ( putf8string("Общая ком"), putf8string(putf16string(putf8string("Общая ком")))); + PEXPECT_EQ( putf8string("Общая ком"), putf8string(putf16string("Общая ком"))); +} |