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