Boost logo

Boost :

From: Yannick Le Goc (ylegoc_at_[hidden])
Date: 2025-05-06 05:06:39


Another question concerning the memory footprint.

Suppose we have a class hierarchy of size N so that:
struct A1 {...}
struct A2 : A1 {...}
...
struct AN : AN-1 {...}

Now we define an open method with M virtual arguments BOOST_OPENMETHOD(big,
(virtual_ptr<A1>, virtual_ptr<A1>, virtual_ptr<A1>, ..., virtual_ptr<A1>),
void);

What set of overriders would be the worst case in terms of memory footprint
?
I suppose it would be the complete set of overriders that covers all the
tuples possibilty, for which size is N^M.
Then would the size of the dispatch table be O(N^M) ?

On Mon, May 5, 2025 at 3:11 AM Jean-Louis Leroy via Boost <
boost_at_[hidden]> wrote:

> > First, thanks for all the effort you put into writing a solid library on
> an
> > experimental subject.
>
> Hi Yannick! Thank you for the feedback.
>
> > 1. Concerning the overrider selection, when the perfect match is not
> found, it
> > is said that an arbitrary choice is made.
>
> Everybody seems to dislike this, including myself. It is the behavior
> specified
> in N2216.
>
> > My tests on virtual inheritance and two dimensions dispatch showed that
> this
> > is the last defined compatible overrider that is chosen. Do you confirm ?
>
> I don't. It's a secret ;-) Only I can use that knowledge in my unit tests.
>
> The only guarantee is that the same overrider is always picked for the
> same set
> of virtual arguments for the duration of the process.
>
> > 2. The class virtual_ptr<Class> accepts only classes that inherit Class.
> Would
> > it be possible to accept inheritance unrelated classes e.g.
> > std::filesystem::path and std::string ?
>
> Not directly. What would the method signature, and the method call look
> like?
> You could wrap them in a class hierarchy, e.g. AbstractPath,
> FileSystemPath and
> StringPath. I have some ideas about supporting std::any virtual
> parameters though,
> where the overriders would specify an exact type, something like:
>
> BOOST_OPENMETHOD(delete, (virtual_<std::any> path), void);
>
> BOOST_OPENMETHOD_OVERRIDE(delete, (std::filesystem::path path), void) {
> ...
> }
>
> BOOST_OPENMETHOD_OVERRIDE(delete, (std::string path), void) {
> ...
> }
>
> > 3. Would it be possible to get rid of the class declarations ? Indeed
> they are
> > already declared in the template parameter of the virtual_ptr<>
> arguments
> > so they could be implicitly defined here.
>
> Ah but you are forgetting about intermediate classes in the hierarchy,
> between
> the method and the overrider:
>
> struct A { ... };
> struct I : A { ... };
> struct B : I { ... };
>
> BOOST_OPENMETHOD(whatever, (virtual_ptr<A>), void);
>
> BOOST_OPENMETHOD_OVERRIDE(whatever, (virtual_ptr<B>), void) {
> ...
> }
>
> auto p = std::make_unique<I>();
> whatever(*p);
>
> That being said, with_vptr must be called at every level of the hierarchy,
> and
> indeed, it does class registration for you.
>
> At some point in the future, reflection might be good enough to help with
> this.
>
> J-L
>
> On Sun, May 4, 2025 at 4:11 PM Yannick Le Goc <ylegoc_at_[hidden]> wrote:
> >
> > Hi Jean-Louis,
> >
> > First, thanks for all the effort you put into writing a solid library on
> an experimental subject.
> > I have a few questions.
> >
> > 1. Concerning the overrider selection, when the perfect match is not
> found, it is said that an arbitrary choice is made.
> > My tests on virtual inheritance and two dimensions dispatch showed that
> this is the last defined compatible overrider that is chosen.
> > Do you confirm ? Or what is the algorithm ?
> >
> > 2. The class virtual_ptr<Class> accepts only classes that inherit Class.
> Would it be possible to accept inheritance unrelated classes e.g.
> std::filesystem::path and std::string ?
> >
> > 3. Would it be possible to get rid of the class declarations ? Indeed
> they are already declared in the template parameter of the virtual_ptr<>
> arguments so they could be implicitly defined here.
> >
> > Yannick
> >
> >
> > On Sun, May 4, 2025 at 11:15 AM Jean-Louis Leroy via Boost <
> boost_at_[hidden]> wrote:
> >>
> >> > struct dynamic_policy
> >> > :
> boost::openmethod::default_policy::fork<dynamic_policy>::replace<
> >> > boost::openmethod::policies::extern_vptr,
> >> > boost::openmethod::policies::vptr_vector<
> >> > dynamic_policy,
> >> > boost::openmethod::policies::indirect_vptr>> {};
> >> >
> >> > Committing this code to any project I've worked on would've left most
> of my
> >> > coworkers absolutely checked out.
> >>
> >> With the changes in the review branch, you can now say:
> >>
> >> struct dynamic_policy
> >> : boost::openmethod::default_policy::fork<dynamic_policy>::add<
> >> boost::openmethod::policies::indirect_vptr>> {};
> >>
> >> I am pretty sure I can make this work:
> >>
> >> struct map_policy
> >> : default_policy::fork<map_policy>::with<vptr_map<map_policy>>
> {};
> >>
> >> I.e. instead of saying `replace<Facet1,
> Implementation1>::replace<Facet2,
> >> Implementation2>` you can just say `with<Implementation1,
> Implementation2>`. If
> >> an implementation of the same facet exists in the policy, it will be
> replaced
> >> with the new one, otherwise the implementation will be added. Not in
> the review
> >> branch yet.
> >>
> >> _______________________________________________
> >> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk