From 71063047d876265be7afffcafd0ca2615773a2bb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 9 Dec 2025 10:47:01 -0500 Subject: [PATCH] xo-alloc2: utest improvements [not working state] --- utest/objectmodel.test.cpp | 77 ++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/utest/objectmodel.test.cpp b/utest/objectmodel.test.cpp index 69f652e..8bf1fb6 100644 --- a/utest/objectmodel.test.cpp +++ b/utest/objectmodel.test.cpp @@ -114,7 +114,7 @@ namespace xo { * such as IComplex_RectCoords or IComplex_PolarCoords. **/ struct IComplex_Any : public AComplex { - virtual double xcoord(void *) const final override { assert(false); return 0.0; } + virtual double xcoord(void *) const final override { assert(false); return 0.0; } virtual double ycoord(void *) const final override { assert(false); return 0.0; } virtual double argument(void *) const final override { assert(false); return 0.0; } virtual double magnitude(void *) const final override { assert(false); return 0.0; } @@ -327,10 +327,10 @@ namespace xo { RComplex() {} RComplex(Object::DataBox data) : Object{std::move(data)} {} - double xcoord() const { return Object::_xcoord(Object::data()); } - double ycoord() const { return Object::_ycoord(Object::data()); } - double argument() const { return Object::_argument(Object::data()); } - double magnitude() const { return Object::_magnitude(Object::data()); } + double xcoord() const { return Object::xcoord(Object::data()); } + double ycoord() const { return Object::ycoord(Object::data()); } + double argument() const { return Object::argument(Object::data()); } + double magnitude() const { return Object::magnitude(Object::data()); } }; template @@ -364,10 +364,32 @@ namespace xo { /** boxed object, held by unique-pointer equiavelent. * * Example: - * std::unique_ptr z1_in = std::make_unique(1.0, 0.0): + * std::unique_ptr z1_in + * = std::make_unique(1.0, 0.0): * uany z1{z1_in.release()}; - * * z1.xcoord(); + * + * + * +-----+ +-----------------+ + * Interface | x-------------->| vtable for | + * +-----+ | some descendant | + * Data | x--------\ | of AInterface | + * +-----+ | | | + * | +-----------------+ + * | + * | +--------------+ + * \----->| data :: Repr | + * +--------------+ + * + * Binary representaiton of unay + * is compatible for different values of @tparam Data + * as long as vtable pointer moves along with data pointer. + * + * In particular binary representation for + * uany is as if it inherited uany + * (even though it does not as far as compiler is concerned) + * + * This is load-bearing for @ref move2any see below **/ template struct uany : public RoutingType> { @@ -376,6 +398,18 @@ namespace xo { uany() {} explicit uany(Super::DataBox d) : Super(d) {} + /** copy contents of this instance into *dest. + **/ + void move2any(uany * dest) { + static_assert(sizeof(uany) + == sizeof(uany)); + + ::memcpy((void*)dest, (void*)this, sizeof(uany)); + // this is almost right. But doesn't copy vtable pointer + //*dest = *(reinterpret_cast*>(this)); + this->data_ = nullptr; + } + /** move constructor from a different representation. * allowed given: * - same abstract interface @@ -385,10 +419,14 @@ namespace xo { uany(uany && other) requires (std::is_same_v || std::is_convertible_v) - : Super(reinterpret_cast) + == sizeof(uany)); + + other.move2any(this); + + assert(other.data_ = nullptr); } }; @@ -497,8 +535,23 @@ namespace xo { /* equivalent to ubox, but impl doesn't use std::unique_ptr */ uany z1{new DRectCoords{1.0, 0.0}}; - /* should be able to assign to a variant uany */ - uany uany = std::move(z1); + DRectCoords * z1_data = z1.data(); + + REQUIRE(z1.data() != nullptr); + REQUIRE(z1.xcoord() == 1.0); + + /* can type-erase */ + uany z1_any; + + REQUIRE(z1_any.data() == nullptr); + + z1.move2any(&z1_any); + + /* z1 should be empty, it moved itself */ + REQUIRE(z1.data() == nullptr); + REQUIRE((void*)z1_any.data() == (void*)z1_data); + + REQUIRE(z1_any.xcoord() == 1.0); } } /*namespace ut*/ } /*namespace xo*/