// Boost.TypeErasure library // // Copyright 2011 Steven Watanabe // // Distributed under the Boost Software License Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // $Id$ //[multifunction /*` (For the source of this example see [@boost:/libs/type_erasure/example/multifunction.cpp multifunction.cpp]) This example implements an extension of Boost.Function that supports multiple signatures. [note This example uses C++11 features. You'll need a recent compiler for it to work.] */ #include #include #include #include #include #include #include #include #include #include #include #include namespace mpl = boost::mpl; using namespace boost::type_erasure; namespace phoenix = boost::phoenix; // First of all we'll declare the multifunction template. // multifunction is like Boost.Function but instead of // taking one signature, it takes any number of them. template using multifunction = any< mpl::vector< copy_constructible<>, typeid_<>, relaxed, callable... > >; // Let's use multifunction to process a variant. We'll start // by defining a simple recursive variant to use. typedef boost::make_recursive_variant< int, double, std::string, std::vector >::type variant_type; typedef std::vector vector_type; // Now we'll define a multifunction that can operate // on the leaf nodes of the variant. typedef multifunction function_type; class variant_handler { public: void handle(const variant_type& arg) { boost::apply_visitor(impl, arg); } void set_handler(function_type f) { impl.f = f; } private: // A class that works with boost::apply_visitor struct dispatcher : boost::static_visitor { // used for the leaves template void operator()(const T& t) { f(t); } // For a vector, we recursively operate on the elements void operator()(const vector_type& v) { boost::for_each(v, boost::apply_visitor(*this)); } function_type f; }; dispatcher impl; }; int main() { variant_handler x; x.set_handler(std::cout << phoenix::val("Value: ") << phoenix::placeholders::_1 << std::endl); x.handle(1); x.handle(2.718); x.handle("The quick brown fox jumps over the lazy dog."); x.handle(vector_type{ 1.618, "Gallia est omnis divisa in partes tres", 42 }); } //]