$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] More flexible any_cast for boost::any
From: DeadMG (wolfeinstein_at_[hidden])
Date: 2013-11-26 10:24:00
Hello,
I've been looking at ABIs and such (various unpleasant reasons). But I
recently created the following code:
#include <iostream>
struct Base {
    virtual void check() = 0;
    template<typename T> T* IsDerivedFrom() {
        try {
            check();
        } catch(T* p) {
            return p;
        } catch(...) {
            return nullptr;
        }
        return nullptr;
    }
};
template<typename T> struct Derived : public Base {
    Derived(T obj) : t(obj) {}
    T t;
    void check() override final {
        throw &t;
    }
};
struct A { virtual ~A() {} virtual void print() = 0;};
struct B : public A { int x; B(int y) : x(y) {} void print() override final
{ std::cout << x; } };
int main() {
    Base* b = new Derived<B>(B(5));
    A* p = b->IsDerivedFrom<A>();
    p->print();
}
Whilst this is hardly the cleanest piece of code I've ever written, it also
provides a base for implementing a more generic any_cast<ValueType>, which
could succeed if ValueType is a base class of the stored type. Amazingly,
the Standard requires the code to work but does not provide a cleaner means
of implementation.
I also note that, for some configurations, you could fall back to the
Itanium ABI provided function directly, which would presumably be
substantially faster and cleaner.
Enabling this variety of any_cast would substantially improve the
composability of boost::any. For example, it's arguable that std::function
is merely boost::any but with additional interface requirements. With such
an any_cast enhancement, it would be quite trivial to compose std::function
implementations or similar concepts on top of boost::any.