boost::openmethod::virtual_any

A wide any, combining an any and a pointer to a v‐table.

Synopsis

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

template<
    class Any,
    class Registry = boost::openmethod::default_registry>
class virtual_any;

Description

virtual_any is to any what virtual_ptr is to a pointer: it carries the v‐table pointer for the value stored in the any, so methods dispatch on the contained type without looking it up on every call. Unlike virtual_ptr, it owns its object: the any is held by value.

The v‐table pointer is acquired when the virtual_any is created: either from the dynamic type of an existing any (a hash table lookup, via virtual_traits<const Any&, Registry>::vptr), or statically, when the contained type is known at compile time (the value constructor and emplace use registry::static_vptr).

Contained types are registered automatically, as classes derived from Any: naming a type as the parameter of an overrider ‐ or storing a value in a virtual_any ‐ registers it in Registry.

Methods take virtual_any parameters by reference: `const virtual_any&`, virtual_any& or virtual_any&&`. Overriders receive the contained type, by a reference of a compatible category ‐ or the `virtual_any itself, unchanged, for a catch‐all overrider.

The contained value cannot be replaced through a virtual_any other than via assignment or emplace, which re‐derive the v‐table pointer, thus maintaining the invariant that the v‐table pointer corresponds to the contained type.

Any can be std::any, boost::any, or any type that has an any‐like interface, and specializes virtual_traits for its reference types, providing vptr and cast.

Example

struct Dog {
    std::string name;
};

// `std::any` is the common base of the types it may contain. The types are
// registered automatically: naming one in an overrider - or storing a value
// in a `virtual_std_any` - registers it.

BOOST_OPENMETHOD(name, (const virtual_std_any&), std::string);

// An overrider takes the contained value...
BOOST_OPENMETHOD_OVERRIDE(name, (const Dog& dog), std::string) {
    return dog.name + " the dog";
}

BOOST_OPENMETHOD_OVERRIDE(name, (const std::string& name), std::string) {
    return name;
}

BOOST_OPENMETHOD_OVERRIDE(name, (const int& value), std::string) {
    return std::to_string(value) + " the integer";
}

// ...or the `virtual_any` itself, which makes it a catch-all.
BOOST_OPENMETHOD_OVERRIDE(name, (const virtual_std_any& value), std::string) {
    return value.get().has_value() ? "something else" : "nothing";
}

virtual_std_any spot = Dog{"Spot"};

std::cout << name(spot) << "\n"; // Spot the dog

// The value converts to a temporary `virtual_std_any` at the call
// site, which registers `float`. It has no overrider of its own,
// so the catch-all applies.
std::cout << name(3.14f) << "\n"; // something else

Member Functions

Name

Description

virtual_any [constructor]

Constructors

operator=

Assignment operators

emplace

Construct a value in place.

get

Return a reference to the (non‐modifiable) any.

vptr

Return the v‐table pointer.

Template Parameters

Name

Description

Any

An any type.

Registry

A registry.

See Also