$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [type_erasure] Downcasting is now possible
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2015-03-07 23:27:23
AMDG
  I've been asked about a function for downcasting
an any several times, and I finally implemented it.
Short story: you can now use dynamic_any_cast to
convert between two arbitrary any types.
  Here's a quick example which tries to cast a
boost::any equivalent to a boost::function
equivalent.
using plain_any = any<mpl::vector<
    copy_constructible<>,
    relaxed> >;
template<class Sig>
using any_function = any<mpl::vector<
    callable<Sig>,
    copy_constructible<>,
    relaxed> >;
bool try_call(const plain_any& arg) {
  try {
    auto fun = dynamic_any_cast<any_function<void()> >(arg);
    fun();
  } catch(bad_any_cast&) {
    return false;
  }
  return true;
}
void global_register() {
  register_binding<copy_constructible<>, void(*)()>();
  register_binding<typeid_<>, void(*)()>();
  register_binding<callable<void()>, void(*)()>();
}
void do_something() {
    std::cout << 42 << std::endl;
}
int main() {
    global_register();
    plain_any x = &do_something;
    if(try_call(x)) {
        std::cout << "x is a function" << std::endl;
    }
    plain_any y = 10;
    if(!try_call(y)) {
        std::cout << "y is NOT a function" << std::endl;
    }
}
  The calls to register_binding are necessary for
this to work, unfortunately.  I don't think it's
possible to implement dynamic_any_cast without
some kind of registration, but at least it only
needs to be called once for each concept/type
combination.  If anyone has any better ideas
about how to handle this, I'd love to hear it.
Comments, questions, and criticism are welcome.
In Christ,
Steven Watanabe