|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r83378 - in sandbox/type_erasure/libs/type_erasure: doc example
From: steven_at_[hidden]
Date: 2013-03-09 16:53:15
Author: steven_watanabe
Date: 2013-03-09 16:53:14 EST (Sat, 09 Mar 2013)
New Revision: 83378
URL: http://svn.boost.org/trac/boost/changeset/83378
Log:
New example: multifunction.
Added:
sandbox/type_erasure/libs/type_erasure/example/multifunction.cpp (contents, props changed)
Text files modified:
sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk | 5 +++++
sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam | 1 +
2 files changed, 6 insertions(+), 0 deletions(-)
Modified: sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk (original)
+++ sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk 2013-03-09 16:53:14 EST (Sat, 09 Mar 2013)
@@ -233,6 +233,11 @@
[printf]
[endsect]
+[section:multifunction Boost.Function with multiple signatures]
+[import ../example/multifunction.cpp]
+[multifunction]
+[endsect]
+
[endsect]
[section:conceptdef Concept Definitions]
Modified: sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam (original)
+++ sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam 2013-03-09 16:53:14 EST (Sat, 09 Mar 2013)
@@ -21,3 +21,4 @@
run print_sequence.cpp ;
run printf.cpp ;
+run multifunction.cpp ;
Added: sandbox/type_erasure/libs/type_erasure/example/multifunction.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/multifunction.cpp 2013-03-09 16:53:14 EST (Sat, 09 Mar 2013)
@@ -0,0 +1,105 @@
+// 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 <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/callable.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/variant.hpp>
+#include <boost/phoenix/core.hpp>
+#include <boost/phoenix/operator.hpp>
+#include <boost/range/algorithm.hpp>
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <iostream>
+
+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<class... Sig>
+using multifunction =
+ any<
+ mpl::vector<
+ copy_constructible<>,
+ typeid_<>,
+ relaxed,
+ callable<Sig>...
+ >
+ >;
+
+// 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<boost::recursive_variant_> >::type variant_type;
+typedef std::vector<variant_type> vector_type;
+
+// Now we'll define a multifuntion that can operate
+// on the leaf nodes of the variant.
+typedef multifunction<void(int), void(double), void(std::string)> 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<void>
+ {
+ // used for the leaves
+ template<class T>
+ 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 });
+}
+
+//]
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk