boost::openmethod::openmethod_vptr

A Boost.TypeErasure concept that makes an any intrinsically polymorphic.

Synopsis

Declared in <boost/openmethod/interop/boost_type_erasure.hpp>

template<
    class Concept,
    class Registry = boost::openmethod::default_registry,
    typename T = boost::type_erasure::_self>
struct openmethod_vptr;

Description

Including openmethod_vptr<Concept> in a Concept adds an operation, to the dispatch table of every any on Concept, that returns the registry::static_vptr for the bound type; and it surfaces the operation as a boost_openmethod_vptr overload, which dispatch prefers over the registry's vptr policy. Calls thus resolve in constant time, without hashing the result of boost::type_erasure::typeid_of.

In addition, binding a value to such an any registers its type as a class derived from the owning any ‐ the same shape that naming the type as an overrider parameter produces, with which it can coexist.

Concept must be the very Concept the any is instantiated with. Since the concept appears inside that Concept, the Concept must name itself: define it as a struct deriving from the concept list.

Unlike the vptr policy, which reports a missing_class error, calling a method on an empty relaxed any throws boost::type_erasure::bad_function_call.

An any that carries this concept cannot be wrapped in a virtual_any the hook returns the v‐table pointer by value, and an indirect registry cannot store that. Wrapping one is rejected at compile time.

Both give constant‐time access to the v‐table pointer, but not at the same cost. This concept reaches it through an indirect call on the any's own dispatch table; a virtual_any loads it from the wrapper. What the concept saves over a plain any is the hash of boost::type_erasure::typeid_of, not the call.

Example

struct Dog {
    std::string name;
};

// The concept must name the Concept it is part of, so the Concept is
// defined as a struct.
struct Dispatchable : boost::mpl::vector<
                          te::copy_constructible<>, te::relaxed,
                          openmethod_vptr<Dispatchable>> {};

using erased = te::any<Dispatchable>;

// Binding a value to the `any` registers its type.

BOOST_OPENMETHOD(name, (virtual_<const erased&>), std::string);

BOOST_OPENMETHOD_OVERRIDE(name, (const Dog& dog), std::string) {
    return dog.name + " the dog";
}

Static Member Functions

Name

Description

apply

Returns the v‐table pointer for the bound type.

Template Parameters

Name

Description

Concept

The Concept containing this concept.

Registry

A registry.

T

A placeholder; leave it to its default, _self.