summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/fusion/example
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/fusion/example
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/fusion/example')
-rw-r--r--src/boost/libs/fusion/example/cookbook/do_the_bind.cpp268
-rw-r--r--src/boost/libs/fusion/example/cookbook/fill_em_up.cpp105
-rw-r--r--src/boost/libs/fusion/example/extension/Jamfile20
-rw-r--r--src/boost/libs/fusion/example/extension/detail/advance_impl.hpp47
-rw-r--r--src/boost/libs/fusion/example/extension/detail/at_impl.hpp67
-rw-r--r--src/boost/libs/fusion/example/extension/detail/at_key_impl.hpp72
-rw-r--r--src/boost/libs/fusion/example/extension/detail/begin_impl.hpp43
-rw-r--r--src/boost/libs/fusion/example/extension/detail/category_of_impl.hpp34
-rw-r--r--src/boost/libs/fusion/example/extension/detail/deref_data_impl.hpp30
-rw-r--r--src/boost/libs/fusion/example/extension/detail/deref_impl.hpp67
-rw-r--r--src/boost/libs/fusion/example/extension/detail/distance_impl.hpp44
-rw-r--r--src/boost/libs/fusion/example/extension/detail/end_impl.hpp43
-rw-r--r--src/boost/libs/fusion/example/extension/detail/equal_to_impl.hpp38
-rw-r--r--src/boost/libs/fusion/example/extension/detail/has_key_impl.hpp45
-rw-r--r--src/boost/libs/fusion/example/extension/detail/is_sequence_impl.hpp34
-rw-r--r--src/boost/libs/fusion/example/extension/detail/is_view_impl.hpp32
-rw-r--r--src/boost/libs/fusion/example/extension/detail/key_of_impl.hpp42
-rw-r--r--src/boost/libs/fusion/example/extension/detail/next_impl.hpp46
-rw-r--r--src/boost/libs/fusion/example/extension/detail/prior_impl.hpp46
-rw-r--r--src/boost/libs/fusion/example/extension/detail/size_impl.hpp36
-rw-r--r--src/boost/libs/fusion/example/extension/detail/value_at_impl.hpp44
-rw-r--r--src/boost/libs/fusion/example/extension/detail/value_at_key_impl.hpp50
-rw-r--r--src/boost/libs/fusion/example/extension/detail/value_of_data_impl.hpp30
-rw-r--r--src/boost/libs/fusion/example/extension/detail/value_of_impl.hpp49
-rw-r--r--src/boost/libs/fusion/example/extension/example_struct.hpp25
-rw-r--r--src/boost/libs/fusion/example/extension/example_struct_iterator.hpp70
-rw-r--r--src/boost/libs/fusion/example/extension/example_struct_type.hpp27
-rw-r--r--src/boost/libs/fusion/example/extension/tag_of.hpp30
-rw-r--r--src/boost/libs/fusion/example/extension/test_example.cpp65
-rw-r--r--src/boost/libs/fusion/example/extension/triple.cpp377
-rw-r--r--src/boost/libs/fusion/example/performance/Jamfile20
-rw-r--r--src/boost/libs/fusion/example/performance/accumulate.cpp357
-rw-r--r--src/boost/libs/fusion/example/performance/functional.cpp307
-rw-r--r--src/boost/libs/fusion/example/performance/inner_product.cpp184
-rw-r--r--src/boost/libs/fusion/example/performance/inner_product2.cpp206
-rw-r--r--src/boost/libs/fusion/example/performance/measure.hpp85
-rw-r--r--src/boost/libs/fusion/example/performance/sequence_efficiency.cpp248
-rw-r--r--src/boost/libs/fusion/example/performance/timings.txt57
-rw-r--r--src/boost/libs/fusion/example/performance/zip_efficiency.cpp155
39 files changed, 3545 insertions, 0 deletions
diff --git a/src/boost/libs/fusion/example/cookbook/do_the_bind.cpp b/src/boost/libs/fusion/example/cookbook/do_the_bind.cpp
new file mode 100644
index 00000000..ac5baee4
--- /dev/null
+++ b/src/boost/libs/fusion/example/cookbook/do_the_bind.cpp
@@ -0,0 +1,268 @@
+/*=============================================================================
+ Copyright (c) 2006-2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+
+ Problem:
+
+ How to "do the Bind?"
+
+ This recipe shows how to implement a function binder, similar to
+ Boost.Bind based on the Functional module of Fusion.
+
+ It works as follows:
+
+ 'bind' is a global, stateless function object. It is implemented in
+ fused form (fused_binder) and transformed into a variadic function
+ object. When called, 'bind' returns another function object, which
+ holds the arguments of the call to 'bind'. It is, again, implemented
+ in fused form (fused_bound_function) and transformed into unfused
+ form.
+==============================================================================*/
+
+
+#include <boost/fusion/functional/invocation/invoke.hpp>
+#include <boost/fusion/functional/adapter/unfused.hpp>
+#include <boost/fusion/support/deduce_sequence.hpp>
+
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/sequence/intrinsic/front.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/algorithm/transformation/transform.hpp>
+#include <boost/fusion/algorithm/transformation/pop_front.hpp>
+#include <boost/fusion/algorithm/iteration/fold.hpp>
+#include <boost/fusion/view/filter_view.hpp>
+
+#include <boost/functional/forward_adapter.hpp>
+#include <boost/functional/lightweight_forward_adapter.hpp>
+
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/max.hpp>
+#include <boost/mpl/next.hpp>
+
+#include <boost/ref.hpp>
+#include <iostream>
+#include <typeinfo>
+
+namespace impl
+{
+ namespace fusion = boost::fusion;
+ namespace traits = boost::fusion::traits;
+ namespace result_of = boost::fusion::result_of;
+ namespace mpl = boost::mpl;
+ using mpl::placeholders::_;
+
+ // Placeholders (we inherit from mpl::int_, so we can use placeholders
+ // as indices for fusion::at, later)
+ template <int I> struct placeholder : mpl::int_<I> { };
+
+ // A traits class to find out whether T is a placeholeder
+ template <typename T> struct is_placeholder : mpl::false_ { };
+ template <int I> struct is_placeholder< placeholder<I> > : mpl::true_ { };
+ template <int I> struct is_placeholder< placeholder<I> & > : mpl::true_ { };
+ template <int I> struct is_placeholder< placeholder<I> const > : mpl::true_ { };
+ template <int I> struct is_placeholder< placeholder<I> const & > : mpl::true_ { };
+
+ // This class template provides a Polymorphic Function Object to be used
+ // with fusion::transform. It is applied to the sequence of arguments that
+ // describes the binding and holds a reference to the sequence of arguments
+ // from the final call.
+ template<class FinalArgs> struct argument_transform
+ {
+ FinalArgs const & ref_final_args;
+ public:
+
+ explicit argument_transform(FinalArgs const & final_args)
+ : ref_final_args(final_args)
+ { }
+
+ // A placeholder? Replace it with an argument from the final call...
+ template <int Index>
+ inline typename result_of::at_c<FinalArgs const, Index>::type
+ operator()(placeholder<Index> const &) const
+ {
+ return fusion::at_c<Index>(this->ref_final_args);
+ }
+ // ...just return the bound argument, otherwise.
+ template <typename T> inline T & operator()(T & bound) const
+ {
+ return bound;
+ }
+
+ template <typename Signature>
+ struct result;
+
+ template <class Self, typename T>
+ struct result< Self (T) >
+ : mpl::eval_if< is_placeholder<T>,
+ result_of::at<FinalArgs,typename boost::remove_reference<T>::type>,
+ mpl::identity<T>
+ >
+ { };
+ };
+
+ // Fused implementation of the bound function, the function object
+ // returned by bind
+ template <class BindArgs> class fused_bound_function
+ {
+ // Transform arguments to be held by value
+ typedef typename traits::deduce_sequence<BindArgs>::type bound_args;
+
+ bound_args fsq_bind_args;
+ public:
+
+ fused_bound_function(BindArgs const & bind_args)
+ : fsq_bind_args(bind_args)
+ { }
+
+ template <typename Signature>
+ struct result;
+
+ template <class FinalArgs>
+ struct result_impl
+ : result_of::invoke< typename result_of::front<bound_args>::type,
+ typename result_of::transform<
+ typename result_of::pop_front<bound_args>::type,
+ argument_transform<FinalArgs> const
+ >::type
+ >
+ { };
+
+ template <class Self, class FinalArgs>
+ struct result< Self (FinalArgs) >
+ : result_impl< typename boost::remove_reference<FinalArgs>::type >
+ { };
+
+ template <class FinalArgs>
+ inline typename result_impl<FinalArgs>::type
+ operator()(FinalArgs const & final_args) const
+ {
+ return fusion::invoke( fusion::front(this->fsq_bind_args),
+ fusion::transform( fusion::pop_front(this->fsq_bind_args),
+ argument_transform<FinalArgs>(final_args) ) );
+ }
+ // Could add a non-const variant - omitted for readability
+
+ };
+
+ // Find the number of placeholders in use
+ struct n_placeholders
+ {
+ struct fold_op
+ {
+ template <typename Sig> struct result;
+ template <class S, class A, class B> struct result< S(A &,B &) >
+ : mpl::max<A,B> { };
+ };
+ struct filter_pred
+ {
+ template <class X> struct apply : is_placeholder<X> { };
+ };
+
+ template <typename Seq>
+ struct apply
+ : mpl::next< typename result_of::fold<
+ fusion::filter_view<Seq,filter_pred>, mpl::int_<-1>, fold_op
+ >::type>::type
+ { };
+ };
+
+ // Fused implementation of the 'bind' function
+ struct fused_binder
+ {
+ template <class Signature>
+ struct result;
+
+ template <class BindArgs,
+ int Placeholders = n_placeholders::apply<BindArgs>::value>
+ struct result_impl
+ {
+ typedef boost::forward_adapter<fusion::unfused<
+ fused_bound_function<BindArgs>,!Placeholders>,Placeholders> type;
+ };
+
+ template <class Self, class BindArgs>
+ struct result< Self (BindArgs) >
+ : result_impl< typename boost::remove_reference<BindArgs>::type >
+ { };
+
+ template <class BindArgs>
+ inline typename result_impl< BindArgs >::type
+ operator()(BindArgs & bind_args) const
+ {
+ return typename result< void(BindArgs) >::type(
+ fusion::unfused< fused_bound_function<BindArgs>,
+ ! n_placeholders::apply<BindArgs>::value >(bind_args) );
+ }
+ };
+
+ // The binder's unfused type. We use lightweght_forward_adapter to make
+ // that thing more similar to Boost.Bind. Because of that we have to use
+ // Boost.Ref (below in the sample code)
+ typedef boost::lightweight_forward_adapter< fusion::unfused<fused_binder> > binder;
+}
+
+// Placeholder globals
+impl::placeholder<0> const _1_ = impl::placeholder<0>();
+impl::placeholder<1> const _2_ = impl::placeholder<1>();
+impl::placeholder<2> const _3_ = impl::placeholder<2>();
+impl::placeholder<3> const _4_ = impl::placeholder<3>();
+
+// The bind function is a global, too
+impl::binder const bind = impl::binder();
+
+
+// OK, let's try it out:
+
+struct func
+{
+ typedef int result_type;
+
+ inline int operator()() const
+ {
+ std::cout << "operator()" << std::endl;
+ return 0;
+ }
+
+ template <typename A>
+ inline int operator()(A const & a) const
+ {
+ std::cout << "operator()(A const & a)" << std::endl;
+ std::cout << " a = " << a << " A = " << typeid(A).name() << std::endl;
+ return 1;
+ }
+
+ template <typename A, typename B>
+ inline int operator()(A const & a, B & b) const
+ {
+ std::cout << "operator()(A const & a, B & b)" << std::endl;
+ std::cout << " a = " << a << " A = " << typeid(A).name() << std::endl;
+ std::cout << " b = " << b << " B = " << typeid(B).name() << std::endl;
+ return 2;
+ }
+};
+
+int main()
+{
+ func f;
+ int value = 42;
+ using boost::ref;
+
+ int errors = 0;
+
+ errors += !( bind(f)() == 0);
+ errors += !( bind(f,"Hi")() == 1);
+ errors += !( bind(f,_1_)("there.") == 1);
+ errors += !( bind(f,"The answer is",_1_)(12) == 2);
+ errors += !( bind(f,_1_,ref(value))("Really?") == 2);
+ errors += !( bind(f,_1_,_2_)("Dunno. If there is an answer, it's",value) == 2);
+
+ return !! errors;
+}
+
diff --git a/src/boost/libs/fusion/example/cookbook/fill_em_up.cpp b/src/boost/libs/fusion/example/cookbook/fill_em_up.cpp
new file mode 100644
index 00000000..9b37aec8
--- /dev/null
+++ b/src/boost/libs/fusion/example/cookbook/fill_em_up.cpp
@@ -0,0 +1,105 @@
+/*=============================================================================
+ Copyright (c) 2011 Joel de Guzman
+
+ 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)
+
+ Problem:
+
+ So... you have an input sequence I and a target vector R. You want to
+ copy I into R. But, I may have less elements than the result vector R.
+ For those elements not in R, you want them to be default constructed.
+
+ Here's a case:
+
+ I: list<double, std::string>
+ R: vector<double, std::string, int, short>
+
+ You want the elements at the right of I not in R (i.e. int, short)
+ default constructed. Those at the left, found in both I and R, you want
+ to simply copy from I.
+
+ Of course you want to be able to handle any type of I and R.
+
+==============================================================================*/
+
+// We'll use these containers as examples
+#include <boost/fusion/container/list.hpp>
+#include <boost/fusion/container/vector.hpp>
+
+// For doing I/O
+#include <boost/fusion/sequence/io.hpp>
+
+// We'll use join and advance for processing
+#include <boost/fusion/algorithm/transformation/join.hpp>
+#include <boost/fusion/iterator/advance.hpp>
+
+// The fusion <--> MPL link header
+#include <boost/fusion/mpl.hpp>
+
+// Same-o same-o
+#include <iostream>
+#include <string>
+
+int
+main()
+{
+ using namespace boost::fusion;
+ using namespace boost;
+
+ // Let's specify our own tuple delimeters for nicer printing
+ std::cout << tuple_open('[');
+ std::cout << tuple_close(']');
+ std::cout << tuple_delimiter(", ");
+
+ // Here's your input sequence
+ typedef list<double, std::string> I;
+ I i(123.456, "Hello");
+
+ // Here's your output sequence. For now, it is just a typedef
+ typedef vector<double, std::string, int, short> R;
+
+ // Let's get the sizes of the sequences. Yeah, you already know that.
+ // But with templates, you are simply given, say, R and I, corresponding
+ // to the types of the sequences. You'll have to deal with it generically.
+ static int const r_size = result_of::size<R>::value;
+ static int const i_size = result_of::size<I>::value;
+
+ // Make sure that I has no more elements than R
+ // Be nice and catch obvious errors earlier rather than later.
+ // Without this assert, the mistake will still be caught by Fusion,
+ // but the error will point to somewhere really obscure.
+ BOOST_STATIC_ASSERT(i_size <= r_size);
+
+ // Let's get the begin and end iterator types of the output sequence
+ // There's no actual vector yet. We just want to know the types.
+ typedef result_of::begin<R>::type r_begin;
+ typedef result_of::end<R>::type r_end;
+
+ // Let's skip i_size elements from r_begin. Again, we just want to know the type.
+ typedef result_of::advance_c<r_begin, i_size>::type r_advance;
+
+ // Now, make MPL iterators from r_advance and r_end. Ditto, just types.
+ typedef mpl::fusion_iterator<r_advance> mpl_r_advance;
+ typedef mpl::fusion_iterator<r_end> mpl_r_end;
+
+ // Make an mpl::iterator_range from the MPL iterators we just created
+ // You guessed it! --just a type.
+ typedef mpl::iterator_range<mpl_r_advance, mpl_r_end> tail;
+
+ // Use join to join the input sequence and our mpl::iterator_range
+ // Our mpl::iterator_range is 'tail'. Here, we'll actually instantiate
+ // 'tail'. Notice that this is a flyweight object, typically just 1 byte
+ // in size -- it doesn't really hold any data, but is a fully conforming
+ // sequence nonetheless. When asked to return its elements, 'tail' returns
+ // each element default constructed. Breeds like a rabbit!
+
+ // Construct R from the joined sequences:
+ R r(join(i, tail()));
+
+ // Then finally, print the result:
+ std::cout << r << std::endl;
+
+ return 0;
+}
+
diff --git a/src/boost/libs/fusion/example/extension/Jamfile b/src/boost/libs/fusion/example/extension/Jamfile
new file mode 100644
index 00000000..aabe8302
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/Jamfile
@@ -0,0 +1,20 @@
+#==============================================================================
+# Copyright (c) 2003-2006 Joel de Guzman
+# Copyright (c) 2006 Dan Marsden
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+
+# bring in rules for testing
+import testing ;
+
+{
+ test-suite example :
+
+ [ run test_example.cpp : : : : ]
+ [ run triple.cpp : : : : ]
+ ;
+}
+
diff --git a/src/boost/libs/fusion/example/extension/detail/advance_impl.hpp b/src/boost/libs/fusion/example/extension/detail/advance_impl.hpp
new file mode 100644
index 00000000..0d778123
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/advance_impl.hpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_ADVANCE_IMPL_20060222_2150)
+#define BOOST_FUSION_ADVANCE_IMPL_20060222_2150
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct advance_impl;
+
+ template<>
+ struct advance_impl<example::example_struct_iterator_tag>
+ {
+ template<typename Iterator, typename N>
+ struct apply
+ {
+ typedef typename Iterator::struct_type struct_type;
+ typedef typename Iterator::index index;
+ typedef example::example_struct_iterator<
+ struct_type, index::value + N::value> type;
+
+ static type
+ call(Iterator const& it)
+ {
+ return type(it.struct_);
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/at_impl.hpp b/src/boost/libs/fusion/example/extension/detail/at_impl.hpp
new file mode 100644
index 00000000..60558930
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/at_impl.hpp
@@ -0,0 +1,67 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_AT_IMPL_20060223_2017)
+#define BOOST_FUSION_AT_IMPL_20060223_2017
+
+#include <string>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct at_impl;
+
+ template<>
+ struct at_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence, typename Key>
+ struct apply;
+
+ template<typename Sequence>
+ struct apply<Sequence, mpl::int_<0> >
+ {
+ typedef typename mpl::if_<
+ is_const<Sequence>,
+ std::string const&,
+ std::string&>::type type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return seq.name;
+ };
+ };
+
+ template<typename Sequence>
+ struct apply<Sequence, mpl::int_<1> >
+ {
+ typedef typename mpl::if_<
+ is_const<Sequence>,
+ int const&,
+ int&>::type type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return seq.age;
+ };
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/at_key_impl.hpp b/src/boost/libs/fusion/example/extension/detail/at_key_impl.hpp
new file mode 100644
index 00000000..e925c62a
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/at_key_impl.hpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_AT_KEY_IMPL_20060223_2017)
+#define BOOST_FUSION_AT_KEY_IMPL_20060223_2017
+
+#include <string>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+namespace fields
+{
+ struct name;
+ struct age;
+}
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct at_key_impl;
+
+ template<>
+ struct at_key_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence, typename Key>
+ struct apply;
+
+ template<typename Sequence>
+ struct apply<Sequence, fields::name>
+ {
+ typedef typename mpl::if_<
+ is_const<Sequence>,
+ std::string const&,
+ std::string&>::type type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return seq.name;
+ };
+ };
+
+ template<typename Sequence>
+ struct apply<Sequence, fields::age>
+ {
+ typedef typename mpl::if_<
+ is_const<Sequence>,
+ int const&,
+ int&>::type type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return seq.age;
+ };
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/begin_impl.hpp b/src/boost/libs/fusion/example/extension/detail/begin_impl.hpp
new file mode 100644
index 00000000..a4296c59
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/begin_impl.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_BEGIN_IMPL_20060222_2042)
+#define BOOST_FUSION_BEGIN_IMPL_20060222_2042
+
+#include "../example_struct_iterator.hpp"
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct begin_impl;
+
+ template<>
+ struct begin_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef example::example_struct_iterator<Sequence, 0> type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return type(seq);
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/category_of_impl.hpp b/src/boost/libs/fusion/example/extension/detail/category_of_impl.hpp
new file mode 100644
index 00000000..b0bc7d90
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/category_of_impl.hpp
@@ -0,0 +1,34 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_CATEGORY_OF_IMPL_20060223_2037)
+#define BOOST_FUSION_CATEGORY_OF_IMPL_20060223_2037
+
+#include <boost/fusion/support/category_of.hpp>
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<>
+ struct category_of_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ struct type : random_access_traversal_tag, associative_tag {};
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/deref_data_impl.hpp b/src/boost/libs/fusion/example/extension/detail/deref_data_impl.hpp
new file mode 100644
index 00000000..c9907d5c
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/deref_data_impl.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2009 Christopher Schmidt
+
+ 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)
+==============================================================================*/
+
+#ifndef BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_DEREF_DATA_IMPL_HPP
+#define BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_DEREF_DATA_IMPL_HPP
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct deref_data_impl;
+
+ template<>
+ struct deref_data_impl<example::example_struct_iterator_tag>
+ : deref_impl<example::example_struct_iterator_tag>
+ {};
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/deref_impl.hpp b/src/boost/libs/fusion/example/extension/detail/deref_impl.hpp
new file mode 100644
index 00000000..7e515e9d
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/deref_impl.hpp
@@ -0,0 +1,67 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_DEREF_IMPL_20060222_1952)
+#define BOOST_FUSION_DEREF_IMPL_20060222_1952
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/mpl/if.hpp>
+
+#include <string>
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct deref_impl;
+
+ template<>
+ struct deref_impl<example::example_struct_iterator_tag>
+ {
+ template<typename Iterator>
+ struct apply;
+
+ template<typename Struct>
+ struct apply<example::example_struct_iterator<Struct, 0> >
+ {
+ typedef typename mpl::if_<
+ is_const<Struct>, std::string const&, std::string&>::type type;
+
+ static type
+ call(example::example_struct_iterator<Struct, 0> const& it)
+ {
+ return it.struct_.name;
+ }
+ };
+
+ template<typename Struct>
+ struct apply<example::example_struct_iterator<Struct, 1> >
+ {
+ typedef typename mpl::if_<
+ is_const<Struct>, int const&, int&>::type type;
+
+ static type
+ call(example::example_struct_iterator<Struct, 1> const& it)
+ {
+ return it.struct_.age;
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/distance_impl.hpp b/src/boost/libs/fusion/example/extension/detail/distance_impl.hpp
new file mode 100644
index 00000000..b138cc4a
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/distance_impl.hpp
@@ -0,0 +1,44 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_DISTANCE_IMPL_20060223_0814)
+#define BOOST_FUSION_DISTANCE_IMPL_20060223_0814
+
+#include <boost/mpl/minus.hpp>
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct distance_impl;
+
+ template<>
+ struct distance_impl<example::example_struct_iterator_tag>
+ {
+ template<typename First, typename Last>
+ struct apply
+ : mpl::minus<typename Last::index, typename First::index>
+ {
+ typedef apply<First, Last> self;
+
+ static typename self::type
+ call(First const& first, Last const& last)
+ {
+ return typename self::type();
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/end_impl.hpp b/src/boost/libs/fusion/example/extension/detail/end_impl.hpp
new file mode 100644
index 00000000..749bb33a
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/end_impl.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_END_IMPL_20060222_2042)
+#define BOOST_FUSION_END_IMPL_20060222_2042
+
+#include "../example_struct_iterator.hpp"
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct end_impl;
+
+ template<>
+ struct end_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef example::example_struct_iterator<Sequence, 2> type;
+
+ static type
+ call(Sequence& seq)
+ {
+ return type(seq);
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/equal_to_impl.hpp b/src/boost/libs/fusion/example/extension/detail/equal_to_impl.hpp
new file mode 100644
index 00000000..8ab27649
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/equal_to_impl.hpp
@@ -0,0 +1,38 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_EQUAL_TO_IMPL_20060223_1941)
+#define BOOST_FUSION_EQUAL_TO_IMPL_20060223_1941
+
+#include <boost/mpl/equal_to.hpp>
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct equal_to_impl;
+
+ template<>
+ struct equal_to_impl<example::example_struct_iterator_tag>
+ {
+ template<typename It1, typename It2>
+ struct apply
+ : mpl::equal_to<
+ typename It1::index,
+ typename It2::index>
+ {};
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/has_key_impl.hpp b/src/boost/libs/fusion/example/extension/detail/has_key_impl.hpp
new file mode 100644
index 00000000..596827ce
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/has_key_impl.hpp
@@ -0,0 +1,45 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_HAS_KEY_IMPL_20060223_2156)
+#define BOOST_FUSION_HAS_KEY_IMPL_20060223_2156
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/or.hpp>
+
+namespace fields
+{
+ struct name;
+ struct age;
+}
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct has_key_impl;
+
+ template<>
+ struct has_key_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence, typename Key>
+ struct apply
+ : mpl::or_<
+ is_same<Key, fields::name>,
+ is_same<Key, fields::age> >
+ {};
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/is_sequence_impl.hpp b/src/boost/libs/fusion/example/extension/detail/is_sequence_impl.hpp
new file mode 100644
index 00000000..e373342a
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/is_sequence_impl.hpp
@@ -0,0 +1,34 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_IS_SEQUENCE_IMPL_20060228_1946)
+#define BOOST_FUSION_IS_SEQUENCE_IMPL_20060228_1946
+
+#include <boost/mpl/bool.hpp>
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion
+{
+ namespace extension
+ {
+ template<typename Tag>
+ struct is_sequence_impl;
+
+ template<>
+ struct is_sequence_impl<example::example_sequence_tag>
+ {
+ template<typename T>
+ struct apply : mpl::true_ {};
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/is_view_impl.hpp b/src/boost/libs/fusion/example/extension/detail/is_view_impl.hpp
new file mode 100644
index 00000000..b2344bf2
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/is_view_impl.hpp
@@ -0,0 +1,32 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_IS_VIEW_IMPL_200604227_2150)
+#define BOOST_FUSION_IS_VIEW_IMPL_200604227_2150
+
+#include <boost/mpl/bool.hpp>
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion
+{
+ namespace extension
+ {
+ template<typename Tag>
+ struct is_view_impl;
+
+ template<>
+ struct is_view_impl<example::example_sequence_tag>
+ : boost::mpl::false_
+ {};
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/key_of_impl.hpp b/src/boost/libs/fusion/example/extension/detail/key_of_impl.hpp
new file mode 100644
index 00000000..6a7a836d
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/key_of_impl.hpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Copyright (c) 2009 Christopher Schmidt
+
+ 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)
+==============================================================================*/
+
+#ifndef BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_KEY_OF_IMPL_HPP
+#define BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_KEY_OF_IMPL_HPP
+
+#include <boost/mpl/if.hpp>
+
+namespace fields
+{
+ struct name;
+ struct age;
+}
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct key_of_impl;
+
+ template<>
+ struct key_of_impl<example::example_struct_iterator_tag>
+ {
+ template<typename It>
+ struct apply
+ : mpl::if_c<!It::index::value, fields::name, fields::age>
+ {};
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/next_impl.hpp b/src/boost/libs/fusion/example/extension/detail/next_impl.hpp
new file mode 100644
index 00000000..8fbaa8b1
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/next_impl.hpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_NEXT_IMPL_20060222_1859)
+#define BOOST_FUSION_NEXT_IMPL_20060222_1859
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct next_impl;
+
+ template<>
+ struct next_impl<example::example_struct_iterator_tag>
+ {
+ template<typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::struct_type struct_type;
+ typedef typename Iterator::index index;
+ typedef example::example_struct_iterator<struct_type, index::value + 1> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(i.struct_);
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/prior_impl.hpp b/src/boost/libs/fusion/example/extension/detail/prior_impl.hpp
new file mode 100644
index 00000000..415692ce
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/prior_impl.hpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_PRIOR_IMPL_20060222_1944)
+#define BOOST_FUSION_PRIOR_IMPL_20060222_1944
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct prior_impl;
+
+ template<>
+ struct prior_impl<example::example_struct_iterator_tag>
+ {
+ template<typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::struct_type struct_type;
+ typedef typename Iterator::index index;
+ typedef example::example_struct_iterator<struct_type, index::value - 1> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(i.struct_);
+ }
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/size_impl.hpp b/src/boost/libs/fusion/example/extension/detail/size_impl.hpp
new file mode 100644
index 00000000..4dc6ec93
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/size_impl.hpp
@@ -0,0 +1,36 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_SIZE_IMPL_20060223_2033)
+#define BOOST_FUSION_SIZE_IMPL_20060223_2033
+
+#include <boost/mpl/int.hpp>
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct size_impl;
+
+ template<>
+ struct size_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence>
+ struct apply
+ : mpl::int_<2>
+ {};
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/value_at_impl.hpp b/src/boost/libs/fusion/example/extension/detail/value_at_impl.hpp
new file mode 100644
index 00000000..6a1d63ef
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/value_at_impl.hpp
@@ -0,0 +1,44 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_VALUE_AT_IMPL_20060223_2025)
+#define BOOST_FUSION_VALUE_AT_IMPL_20060223_2025
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct value_at_impl;
+
+ template<>
+ struct value_at_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence, typename N>
+ struct apply;
+
+ template<typename Sequence>
+ struct apply<Sequence, mpl::int_<0> >
+ {
+ typedef std::string type;
+ };
+
+ template<typename Sequence>
+ struct apply<Sequence, mpl::int_<1> >
+ {
+ typedef int type;
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/value_at_key_impl.hpp b/src/boost/libs/fusion/example/extension/detail/value_at_key_impl.hpp
new file mode 100644
index 00000000..cabc59aa
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/value_at_key_impl.hpp
@@ -0,0 +1,50 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_VALUE_AT_KEY_IMPL_20060223_2025)
+#define BOOST_FUSION_VALUE_AT_KEY_IMPL_20060223_2025
+
+namespace fields
+{
+ struct name;
+ struct age;
+}
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct value_at_key_impl;
+
+ template<>
+ struct value_at_key_impl<example::example_sequence_tag>
+ {
+ template<typename Sequence, typename N>
+ struct apply;
+
+ template<typename Sequence>
+ struct apply<Sequence, fields::name>
+ {
+ typedef std::string type;
+ };
+
+ template<typename Sequence>
+ struct apply<Sequence, fields::age>
+ {
+ typedef int type;
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/value_of_data_impl.hpp b/src/boost/libs/fusion/example/extension/detail/value_of_data_impl.hpp
new file mode 100644
index 00000000..94cdcc30
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/value_of_data_impl.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2009 Christopher Schmidt
+
+ 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)
+==============================================================================*/
+
+#ifndef BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_VALUE_OF_DATA_IMPL_HPP
+#define BOOST_FUSION_EXAMPLE_EXTENSION_DETAIL_VALUE_OF_DATA_IMPL_HPP
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct value_of_data_impl;
+
+ template<>
+ struct value_of_data_impl<example::example_struct_iterator_tag>
+ : value_of_impl<example::example_struct_iterator_tag>
+ {};
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/detail/value_of_impl.hpp b/src/boost/libs/fusion/example/extension/detail/value_of_impl.hpp
new file mode 100644
index 00000000..6fc7e161
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/detail/value_of_impl.hpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_VALUE_OF_IMPL_20060223_1905)
+#define BOOST_FUSION_VALUE_OF_IMPL_20060223_1905
+
+#include <string>
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace extension
+ {
+ template<typename Tag>
+ struct value_of_impl;
+
+ template<>
+ struct value_of_impl<example::example_struct_iterator_tag>
+ {
+ template<typename Iterator>
+ struct apply;
+
+ template<typename Struct>
+ struct apply<example::example_struct_iterator<Struct, 0> >
+ {
+ typedef std::string type;
+ };
+
+ template<typename Struct>
+ struct apply<example::example_struct_iterator<Struct, 1> >
+ {
+ typedef int type;
+ };
+ };
+ }
+}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/example_struct.hpp b/src/boost/libs/fusion/example/extension/example_struct.hpp
new file mode 100644
index 00000000..cbb058f5
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/example_struct.hpp
@@ -0,0 +1,25 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_EXAMPLE_STRUCT)
+#define BOOST_FUSION_EXAMPLE_STRUCT
+
+#include "./tag_of.hpp"
+#include "./example_struct_iterator.hpp"
+#include "./detail/begin_impl.hpp"
+#include "./detail/end_impl.hpp"
+#include "./detail/at_impl.hpp"
+#include "./detail/value_at_impl.hpp"
+#include "./detail/size_impl.hpp"
+#include "./detail/category_of_impl.hpp"
+#include "./detail/at_key_impl.hpp"
+#include "./detail/value_at_key_impl.hpp"
+#include "./detail/has_key_impl.hpp"
+#include "./detail/is_sequence_impl.hpp"
+#include "./detail/is_view_impl.hpp"
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/example_struct_iterator.hpp b/src/boost/libs/fusion/example/extension/example_struct_iterator.hpp
new file mode 100644
index 00000000..fa04f085
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/example_struct_iterator.hpp
@@ -0,0 +1,70 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_EXAMPLE_STRUCT_ITERATOR)
+#define BOOST_FUSION_EXAMPLE_STRUCT_ITERATOR
+
+#include <boost/fusion/support/iterator_base.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/fusion/support/tag_of_fwd.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/static_assert.hpp>
+
+#include "./detail/next_impl.hpp"
+#include "./detail/prior_impl.hpp"
+#include "./detail/deref_impl.hpp"
+#include "./detail/advance_impl.hpp"
+#include "./detail/distance_impl.hpp"
+#include "./detail/value_of_impl.hpp"
+#include "./detail/equal_to_impl.hpp"
+#include "./detail/key_of_impl.hpp"
+#include "./detail/value_of_data_impl.hpp"
+#include "./detail/deref_data_impl.hpp"
+
+namespace example
+{
+ struct example_struct_iterator_tag;
+
+ template<typename Struct, int Pos>
+ struct example_struct_iterator;
+}
+
+namespace boost { namespace fusion {
+
+ namespace traits
+ {
+ template<typename Struct, int Pos>
+ struct tag_of<example::example_struct_iterator<Struct, Pos> >
+ {
+ typedef example::example_struct_iterator_tag type;
+ };
+ }
+}}
+
+namespace example {
+ template<typename Struct, int Pos>
+ struct example_struct_iterator
+ : boost::fusion::iterator_base<example_struct_iterator<Struct, Pos> >
+ {
+ BOOST_STATIC_ASSERT(Pos >=0 && Pos < 3);
+ typedef Struct struct_type;
+ typedef boost::mpl::int_<Pos> index;
+
+ struct category
+ : boost::fusion::random_access_traversal_tag
+ , boost::fusion::associative_tag
+ {};
+
+ example_struct_iterator(Struct& str)
+ : struct_(str) {}
+
+ Struct& struct_;
+ };
+}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/example_struct_type.hpp b/src/boost/libs/fusion/example/extension/example_struct_type.hpp
new file mode 100644
index 00000000..e1d8e175
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/example_struct_type.hpp
@@ -0,0 +1,27 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_EXAMPLE_STRUCT_TYPE)
+#define BOOST_FUSION_EXAMPLE_STRUCT_TYPE
+
+#include <string>
+
+namespace example
+{
+ struct example_struct
+ {
+ std::string name;
+ int age;
+ example_struct(
+ const std::string& n,
+ int a)
+ : name(n), age(a)
+ {}
+ };
+}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/tag_of.hpp b/src/boost/libs/fusion/example/extension/tag_of.hpp
new file mode 100644
index 00000000..083b730c
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/tag_of.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#if !defined(BOOST_FUSION_TAG_OF_20060222_2052)
+#define BOOST_FUSION_TAG_OF_20060222_2052
+
+#include <boost/fusion/support/tag_of_fwd.hpp>
+#include "./example_struct_type.hpp"
+
+namespace example
+{
+ struct example_sequence_tag;
+}
+
+namespace boost { namespace fusion {
+
+namespace traits {
+
+ template<>
+ struct tag_of<example::example_struct>
+ {
+ typedef example::example_sequence_tag type;
+ };
+}}}
+
+#endif
diff --git a/src/boost/libs/fusion/example/extension/test_example.cpp b/src/boost/libs/fusion/example/extension/test_example.cpp
new file mode 100644
index 00000000..581e2300
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/test_example.cpp
@@ -0,0 +1,65 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#include "./example_struct.hpp"
+#include "./example_struct_type.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/fusion/sequence/intrinsic.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/fusion/iterator.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/assert.hpp>
+
+int main()
+{
+ example::example_struct bert("bert", 99);
+ using namespace boost::fusion;
+
+ BOOST_MPL_ASSERT((traits::is_associative<example::example_struct>));
+ BOOST_MPL_ASSERT((traits::is_random_access<example::example_struct>));
+ BOOST_MPL_ASSERT((traits::is_sequence<example::example_struct>));
+
+ BOOST_TEST(deref(begin(bert)) == "bert");
+ BOOST_TEST(*next(begin(bert)) == 99);
+ BOOST_TEST(*prior(end(bert)) == 99);
+ BOOST_TEST(*advance_c<1>(begin(bert)) == 99);
+ BOOST_TEST(*advance_c<-1>(end(bert)) == 99);
+ BOOST_TEST(distance(begin(bert), end(bert)) == 2);
+
+ typedef result_of::begin<example::example_struct>::type first;
+ typedef result_of::next<first>::type second;
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_of<first>::type, std::string>));
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_of<second>::type, int>));
+
+ BOOST_TEST(begin(bert) != end(bert));
+ BOOST_TEST(advance_c<2>(begin(bert)) == end(const_cast<const example::example_struct&>(bert)));
+
+ BOOST_TEST(at_c<0>(bert) == "bert");
+ BOOST_TEST(at_c<1>(bert) == 99);
+
+ BOOST_TEST(at_key<fields::name>(bert) == "bert");
+ BOOST_TEST(at_key<fields::age>(bert) == 99);
+
+ BOOST_TEST(has_key<fields::name>(bert));
+ BOOST_TEST(has_key<fields::age>(bert));
+ BOOST_TEST(!has_key<int>(bert));
+
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_at_c<example::example_struct, 0>::type, std::string>));
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_at_c<example::example_struct, 1>::type, int>));
+
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_at_key<example::example_struct, fields::name>::type, std::string>));
+ BOOST_MPL_ASSERT((boost::is_same<result_of::value_at_key<example::example_struct, fields::age>::type, int>));
+
+ BOOST_TEST(deref_data(begin(bert)) == "bert");
+ BOOST_TEST(deref_data(next(begin(bert))) == 99);
+
+ BOOST_TEST(size(bert) == 2);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/fusion/example/extension/triple.cpp b/src/boost/libs/fusion/example/extension/triple.cpp
new file mode 100644
index 00000000..ac8f18e0
--- /dev/null
+++ b/src/boost/libs/fusion/example/extension/triple.cpp
@@ -0,0 +1,377 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2011 Nathan Ridge
+ Copyright (c) 2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+
+/*=============================================================================
+ An implementation of a std::pair like triple<T0, T1, T2>
+ We use fusion::sequence_facade and fusion::iterator_facade
+ to make our triple a fully conforming Boost.Fusion random
+ traversal sequence.
+==============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/fusion/sequence/sequence_facade.hpp>
+#include <boost/fusion/iterator/iterator_facade.hpp>
+#include <boost/fusion/sequence/intrinsic.hpp>
+#include <boost/fusion/iterator.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/fusion/algorithm/iteration/fold.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/assert.hpp>
+
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <string>
+
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+namespace demo
+{
+ template<typename Seq, int N>
+ struct triple_iterator
+ : fusion::iterator_facade<triple_iterator<Seq, N>,
+ fusion::random_access_traversal_tag>
+ {
+ typedef mpl::int_<N> index;
+ typedef Seq sequence_type;
+
+ triple_iterator(Seq& seq)
+ : seq_(seq) {}
+
+ Seq& seq_;
+
+ template<typename T>
+ struct value_of;
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 0> >
+ : mpl::identity<typename Sq::t0_type>
+ {};
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 1> >
+ : mpl::identity<typename Sq::t1_type>
+ {};
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 2> >
+ : mpl::identity<typename Sq::t2_type>
+ {};
+
+ template<typename T>
+ struct deref;
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 0> >
+ {
+ typedef typename Sq::t0_type& type;
+
+ static type
+ call(triple_iterator<Sq, 0> const& iter)
+ {
+ return iter.seq_.t0;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 0> const>
+ {
+ typedef typename Sq::t0_type const& type;
+
+ static type
+ call(triple_iterator<Sq, 0> const& iter)
+ {
+ return iter.seq_.t0;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 1> >
+ {
+ typedef typename Sq::t1_type& type;
+
+ static type
+ call(triple_iterator<Sq, 1> const& iter)
+ {
+ return iter.seq_.t1;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 1> const>
+ {
+ typedef typename Sq::t1_type const& type;
+
+ static type
+ call(triple_iterator<Sq, 1> const& iter)
+ {
+ return iter.seq_.t1;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 2> >
+ {
+ typedef typename Sq::t2_type& type;
+
+ static type
+ call(triple_iterator<Sq, 2> const& iter)
+ {
+ return iter.seq_.t2;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 2> const>
+ {
+ typedef typename Sq::t2_type const& type;
+
+ static type
+ call(triple_iterator<Sq, 2> const& iter)
+ {
+ return iter.seq_.t2;
+ }
+ };
+
+ template<typename It>
+ struct next
+ {
+ typedef triple_iterator<
+ typename It::sequence_type, It::index::value + 1>
+ type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+
+ template<typename It>
+ struct prior
+ {
+ typedef triple_iterator<
+ typename It::sequence_type, It::index::value - 1>
+ type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+
+ template<typename It1, typename It2>
+ struct distance
+ {
+ typedef typename mpl::minus<
+ typename It2::index, typename It1::index>::type
+ type;
+
+ static type call(It1 const& it1, It2 const& it2)
+ {
+ return type();
+ }
+ };
+
+ template<typename It, typename M>
+ struct advance
+ {
+ typedef triple_iterator<
+ typename It::sequence_type,
+ It::index::value + M::value>
+ type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+ };
+
+ template<typename T0, typename T1, typename T2>
+ struct triple
+ : fusion::sequence_facade<triple<T0, T1, T2>,
+ fusion::random_access_traversal_tag>
+ {
+ triple(T0 const& t0, T1 const& t1, T2 const& t2)
+ : t0(t0), t1(t1), t2(t2)
+ {}
+
+ template<typename Sq>
+ struct begin
+ {
+ typedef demo::triple_iterator<Sq, 0> type;
+
+ static type call(Sq& sq)
+ {
+ return type(sq);
+ }
+ };
+
+ template<typename Sq>
+ struct end
+ {
+ typedef demo::triple_iterator<Sq, 3> type;
+
+ static type call(Sq& sq)
+ {
+ return type(sq);
+ }
+ };
+
+ template<typename Sq>
+ struct size
+ : mpl::int_<3>
+ {};
+
+ template<typename Sq, typename N>
+ struct value_at
+ : value_at<Sq, mpl::int_<N::value> >
+ {};
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<0> >
+ {
+ typedef typename Sq::t0_type type;
+ };
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<1> >
+ {
+ typedef typename Sq::t1_type type;
+ };
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<2> >
+ {
+ typedef typename Sq::t2_type type;
+ };
+
+ template<typename Sq, typename N>
+ struct at
+ : at<Sq, mpl::int_<N::value> >
+ {};
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<0> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t0_type const&
+ , typename Sq::t0_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t0;
+ }
+ };
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<1> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t1_type const&
+ , typename Sq::t1_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t1;
+ }
+ };
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<2> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t2_type const&
+ , typename Sq::t2_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t2;
+ }
+ };
+
+ typedef T0 t0_type;
+ typedef T1 t1_type;
+ typedef T2 t2_type;
+
+ T0 t0;
+ T1 t1;
+ T2 t2;
+ };
+}
+
+struct modifying_fold_functor
+{
+ template <typename T>
+ struct result
+ {
+ typedef bool type;
+ };
+
+ template <typename T>
+ bool operator()(bool b, T&)
+ {
+ return b;
+ }
+};
+
+struct nonmodifying_fold_functor
+{
+ template <typename T>
+ struct result
+ {
+ typedef bool type;
+ };
+
+ template <typename T>
+ bool operator()(bool b, const T&)
+ {
+ return b;
+ }
+};
+
+int main()
+{
+ typedef demo::triple<int, char, std::string> my_triple;
+ my_triple t(101, 'a', "hello");
+ BOOST_TEST(*fusion::begin(t) == 101);
+ BOOST_TEST(*fusion::next(fusion::begin(t)) == 'a');
+ BOOST_TEST(*fusion::prior(fusion::end(t)) == "hello");
+ BOOST_TEST(fusion::distance(fusion::begin(t), fusion::end(t)) == 3);
+ BOOST_TEST(fusion::size(t) == 3);
+ BOOST_MPL_ASSERT((boost::is_same<
+ int, fusion::result_of::value_at_c<my_triple, 0>::type>));
+ BOOST_MPL_ASSERT((boost::is_same<
+ char, fusion::result_of::value_at_c<my_triple, 1>::type>));
+ BOOST_MPL_ASSERT((boost::is_same<
+ std::string, fusion::result_of::value_at_c<my_triple, 2>::type>));
+ BOOST_TEST(fusion::at_c<0>(t) == 101);
+ BOOST_TEST(fusion::at_c<1>(t) == 'a');
+ BOOST_TEST(fusion::at_c<2>(t) == "hello");
+ BOOST_TEST(fusion::fold(t, true, modifying_fold_functor()) == true);
+ BOOST_TEST(fusion::fold(t, true, nonmodifying_fold_functor()) == true);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/fusion/example/performance/Jamfile b/src/boost/libs/fusion/example/performance/Jamfile
new file mode 100644
index 00000000..3b8c8ffc
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/Jamfile
@@ -0,0 +1,20 @@
+#==============================================================================
+# Copyright (c) 2003-2006 Joel de Guzman
+# Copyright (c) 2006 Dan Marsden
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+project fusion-performance ;
+
+exe accumulate : accumulate.cpp ;
+
+exe inner_product : inner_product.cpp ;
+
+exe inner_product2 : inner_product2.cpp ;
+
+exe sequence_efficiency : sequence_efficiency.cpp ;
+
+exe functional : functional.cpp ;
+
diff --git a/src/boost/libs/fusion/example/performance/accumulate.cpp b/src/boost/libs/fusion/example/performance/accumulate.cpp
new file mode 100644
index 00000000..176dc458
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/accumulate.cpp
@@ -0,0 +1,357 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#include <boost/array.hpp>
+#include <boost/timer.hpp>
+
+#include <boost/fusion/algorithm/iteration/accumulate.hpp>
+#include <boost/fusion/algorithm/transformation/transform.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/algorithm/transformation/zip.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/adapted/array.hpp>
+
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <algorithm>
+#include <numeric>
+#include <functional>
+#include <iostream>
+#include <cmath>
+#include <limits>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+int const REPEAT_COUNT = 10;
+
+double const duration = 0.5;
+
+namespace
+{
+ template<int N>
+ double time_for_std_accumulate(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr;
+ std::generate(arr.begin(), arr.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::accumulate(arr.begin(), arr.end(), 0);
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::accumulate(arr.begin(), arr.end(), 0);
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+ struct poly_add
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_add(Lhs,Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + rhs;
+ }
+ };
+
+ struct poly_mult
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_mult(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs * rhs;
+ }
+ };
+
+ template<int N>
+ double time_for_fusion_accumulate(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr;
+ std::generate(arr.begin(), arr.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(arr, 0, poly_add());
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ std::cout << iter << " iterations" << std::endl;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(arr, 0, poly_add());
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ std::cout << ".";
+ std::cout.flush();
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+#if 0
+ template<int N>
+ double time_for_std_inner_product(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+ template<int N>
+ double time_for_fusion_inner_product(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+ struct poly_combine
+ {
+ template<typename Lhs, typename Rhs>
+ struct result
+ {
+ typedef Lhs type;
+ };
+
+ template<typename Lhs, typename Rhs>
+ typename result<Lhs,Rhs>::type
+ operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + boost::fusion::at_c<0>(rhs) * boost::fusion::at_c<1>(rhs);
+ }
+ };
+
+ template<int N>
+ double time_for_fusion_inner_product2(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::zip(arr1, arr2), 0, poly_combine());
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ std::cout << iter << " iterations" << std::endl;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::zip(arr1, arr2), 0, poly_combine());
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+#endif
+}
+
+int main()
+{
+ int total = 0;
+ int res;
+ std::cout << "short accumulate std test " << time_for_std_accumulate<8>(res) << std::endl;
+ total += res;
+ std::cout << "short accumulate fusion test " << time_for_fusion_accumulate<8>(res) << std::endl;
+ total += res;
+
+ std::cout << "medium accumulate std test " << time_for_std_accumulate<64>(res) << std::endl;
+ total += res;
+ std::cout << "medium accumulate fusion test " << time_for_fusion_accumulate<64>(res) << std::endl;
+ total += res;
+
+ std::cout << "long accumulate std test " << time_for_std_accumulate<128>(res) << std::endl;
+ total += res;
+ std::cout << "long accumulate fusion test " << time_for_fusion_accumulate<128>(res) << std::endl;
+ total += res;
+
+#if 0
+ std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
+ total += res;
+ std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
+ total += res;
+ std::cout << "short inner_product fusion 2 test " << time_for_fusion_inner_product2<8>(res) << std::endl;
+ total += res;
+
+ std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
+ total += res;
+ std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
+ total += res;
+ std::cout << "medium inner_product fusion 2 test " << time_for_fusion_inner_product2<64>(res) << std::endl;
+ total += res;
+
+
+ std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
+ total += res;
+ std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
+ total += res;
+ std::cout << "long inner_product fusion 2 test " << time_for_fusion_inner_product2<128>(res) << std::endl;
+ total += res;
+#endif
+
+ return total;
+}
diff --git a/src/boost/libs/fusion/example/performance/functional.cpp b/src/boost/libs/fusion/example/performance/functional.cpp
new file mode 100644
index 00000000..9207a90d
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/functional.cpp
@@ -0,0 +1,307 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2006-2007 Tobias Schwinger
+
+ Use modification and distribution are subject to 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).
+==============================================================================*/
+
+#include <boost/fusion/container/list.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/algorithm/iteration/fold.hpp>
+#include <boost/fusion/functional/adapter/unfused.hpp>
+#include <boost/fusion/functional/adapter/fused_function_object.hpp>
+
+#include <boost/functional/forward_adapter.hpp>
+#include <boost/functional/lightweight_forward_adapter.hpp>
+
+#include <boost/utility/result_of.hpp>
+#include <boost/config.hpp>
+#include <boost/timer.hpp>
+#include <algorithm>
+#include <iostream>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+int const REPEAT_COUNT = 3;
+
+double const duration = 0.125;
+
+
+namespace
+{
+ struct fused_sum
+ {
+ template <typename Seq>
+ int operator()(Seq const & seq) const
+ {
+ int state = 0;
+ return boost::fusion::fold(seq, state, sum_op());
+ }
+
+ typedef int result_type;
+
+ private:
+
+ struct sum_op
+ {
+ template <typename T>
+ int operator()(T const & elem, int value) const
+ {
+ return value + sizeof(T) * elem;
+ }
+
+ template <typename T>
+ int operator()(T & elem, int value) const
+ {
+ elem += sizeof(T);
+ return value;
+ }
+
+ typedef int result_type;
+ };
+ };
+
+ struct unfused_sum
+ {
+ inline int operator()() const
+ {
+ return 0;
+ }
+ template<typename T0>
+ inline int operator()(T0 const & a0) const
+ {
+ return a0;
+ }
+ template<typename T0, typename T1>
+ inline int operator()(T0 const & a0, T1 const & a1) const
+ {
+ return a0 + a1;
+ }
+ template<typename T0, typename T1, typename T2>
+ inline int operator()(T0 const & a0, T1 const & a1, T2 a2) const
+ {
+ return a0 + a1 + a2;
+ }
+ template<typename T0, typename T1, typename T2, typename T3>
+ inline int operator()(T0 const & a0, T1 const & a1, T2 const & a2, T3 const & a3) const
+ {
+ return a0 + a1 + a2 + a3;
+ }
+
+ typedef int result_type;
+ };
+
+ template<typename F>
+ double call_unfused(F const & func, int & j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i += func();
+ i += func(0);
+ i += func(0,1);
+ i += func(0,1,2);
+ i += func(0,1,2,3);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = func(); j += i;
+ i = func(0); j += i;
+ i = func(0,1); j += i;
+ i = func(0,1,2); j += i;
+ i = func(0,1,2,3); j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ return result / iter;
+ }
+
+ template<typename F>
+ double call_fused_ra(F const & func, int & j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ do
+ {
+ boost::fusion::vector<> v0;
+ boost::fusion::vector<int> v1(0);
+ boost::fusion::vector<int,int> v2(0,1);
+ boost::fusion::vector<int,int,int> v3(0,1,2);
+ boost::fusion::vector<int,int,int,int> v4(0,1,2,3);
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i += func(v0);
+ i += func(v1);
+ i += func(v2);
+ i += func(v3);
+ i += func(v4);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ boost::fusion::vector<> v0;
+ boost::fusion::vector<int> v1(0);
+ boost::fusion::vector<int,int> v2(0,1);
+ boost::fusion::vector<int,int,int> v3(0,1,2);
+ boost::fusion::vector<int,int,int,int> v4(0,1,2,3);
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = func(v0); j += i;
+ i = func(v1); j += i;
+ i = func(v2); j += i;
+ i = func(v3); j += i;
+ i = func(v4); j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ return result / iter;
+ }
+
+ template<typename F>
+ double call_fused(F const & func, int & j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ do
+ {
+ boost::fusion::list<> l0;
+ boost::fusion::list<int> l1(0);
+ boost::fusion::list<int,int> l2(0,1);
+ boost::fusion::list<int,int,int> l3(0,1,2);
+ boost::fusion::list<int,int,int,int> l4(0,1,2,3);
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i += func(l0);
+ i += func(l1);
+ i += func(l2);
+ i += func(l3);
+ i += func(l4);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ boost::fusion::list<> l0;
+ boost::fusion::list<int> l1(0);
+ boost::fusion::list<int,int> l2(0,1);
+ boost::fusion::list<int,int,int> l3(0,1,2);
+ boost::fusion::list<int,int,int,int> l4(0,1,2,3);
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = func(l0); j += i;
+ i = func(l1); j += i;
+ i = func(l2); j += i;
+ i = func(l3); j += i;
+ i = func(l4); j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ return result / iter;
+ }
+}
+
+int main()
+{
+ int total = 0;
+ int res;
+ typedef fused_sum F;
+ typedef unfused_sum U;
+
+ std::cout << "Compiler: " << BOOST_COMPILER << std::endl;
+ std::cout << std::endl << "Unfused adapters:" << std::endl;
+ {
+ F f;
+ std::cout << "F /* a fused function object */ " << call_fused_ra(f,res) << std::endl;
+ total += res;
+ }
+ {
+ F f;
+ std::cout << "without random access " << call_fused(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::lightweight_forward_adapter< boost::fusion::unfused<F> > f;
+ std::cout << "lightweight_forward_adapter< unfused<F> > " << call_unfused(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::forward_adapter< boost::fusion::unfused<F> > f;
+ std::cout << "forward_adapter< unfused<F> > " << call_unfused(f,res) << std::endl;
+ total += res;
+ }
+ std::cout << std::endl << "Fused adapters:" << std::endl;
+ {
+ unfused_sum f;
+ std::cout << "U /* an unfused function object */ " << call_unfused(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::fusion::fused_function_object<U> f;
+ std::cout << "fused_function_object<U> " << call_fused_ra(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::fusion::fused_function_object<U> f;
+ std::cout << "without random access " << call_fused(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::lightweight_forward_adapter< boost::fusion::unfused< boost::fusion::fused_function_object<U> > > f;
+ std::cout << "lightweight_forward_adapter< unfused<fused_function_object<U> > >" << call_unfused(f,res) << std::endl;
+ total += res;
+ }
+ {
+ boost::forward_adapter< boost::fusion::unfused< boost::fusion::fused_function_object<U> > > f;
+ std::cout << "forward_adapter< unfused<fused_function_object<U> > > " << call_unfused(f,res) << std::endl;
+ total += res;
+ }
+
+ return total;
+}
diff --git a/src/boost/libs/fusion/example/performance/inner_product.cpp b/src/boost/libs/fusion/example/performance/inner_product.cpp
new file mode 100644
index 00000000..c9f22c7c
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/inner_product.cpp
@@ -0,0 +1,184 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#include <boost/array.hpp>
+#include <boost/timer.hpp>
+
+#include <boost/fusion/algorithm/iteration/accumulate.hpp>
+#include <boost/fusion/algorithm/transformation/transform.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/algorithm/transformation/zip.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/adapted/array.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <algorithm>
+#include <numeric>
+#include <functional>
+#include <iostream>
+#include <cmath>
+#include <limits>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+int const REPEAT_COUNT = 10;
+
+double const duration = 0.5;
+
+namespace
+{
+ struct poly_add
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_add(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + rhs;
+ }
+ };
+
+ struct poly_mult
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_mult(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs * rhs;
+ }
+ };
+
+ template<int N>
+ double time_for_std_inner_product(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+ template<int N>
+ double time_for_fusion_inner_product(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::transform(arr1, arr2, poly_mult()), 0, poly_add());
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+}
+
+int main()
+{
+ int total = 0;
+ int res;
+
+ std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
+ total += res;
+ std::cout << "short inner_product fusion test " << time_for_fusion_inner_product<8>(res) << std::endl;
+ total += res;
+
+ std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
+ total += res;
+ std::cout << "medium inner_product fusion test " << time_for_fusion_inner_product<64>(res) << std::endl;
+ total += res;
+
+ std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
+ total += res;
+ std::cout << "long inner_product fusion test " << time_for_fusion_inner_product<128>(res) << std::endl;
+ total += res;
+
+ return total;
+}
diff --git a/src/boost/libs/fusion/example/performance/inner_product2.cpp b/src/boost/libs/fusion/example/performance/inner_product2.cpp
new file mode 100644
index 00000000..f1d536af
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/inner_product2.cpp
@@ -0,0 +1,206 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2005-2006 Dan Marsden
+
+ 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)
+==============================================================================*/
+#include <boost/array.hpp>
+#include <boost/timer.hpp>
+
+#include <boost/fusion/algorithm/iteration/accumulate.hpp>
+#include <boost/fusion/algorithm/transformation/transform.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/algorithm/transformation/zip.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/adapted/array.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <algorithm>
+#include <numeric>
+#include <functional>
+#include <iostream>
+#include <cmath>
+#include <limits>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+int const REPEAT_COUNT = 10;
+
+double const duration = 0.5;
+
+namespace
+{
+ struct poly_add
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_add(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + rhs;
+ }
+ };
+
+ struct poly_mult
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_mult(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs * rhs;
+ }
+ };
+
+ template<int N>
+ double time_for_std_inner_product(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = std::inner_product(arr1.begin(), arr1.end(), arr2.begin(), 0);
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+
+ struct poly_combine
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_combine(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ typename result<poly_combine(Lhs,Rhs)>::type
+ operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + boost::fusion::at_c<0>(rhs) * boost::fusion::at_c<1>(rhs);
+ }
+ };
+
+ template<int N>
+ double time_for_fusion_inner_product2(int& j)
+ {
+ boost::timer tim;
+ int i = 0;
+ long long iter = 65536;
+ long long counter, repeats;
+ double result = (std::numeric_limits<double>::max)();
+ double runtime = 0;
+ double run;
+ boost::array<int, N> arr1;
+ boost::array<int, N> arr2;
+ std::generate(arr1.begin(), arr1.end(), rand);
+ std::generate(arr2.begin(), arr2.end(), rand);
+ do
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::zip(arr1, arr2), 0, poly_combine());
+ static_cast<void>(i);
+ }
+ runtime = tim.elapsed();
+ iter *= 2;
+ } while(runtime < duration);
+ iter /= 2;
+
+ std::cout << iter << " iterations" << std::endl;
+
+ // repeat test and report least value for consistency:
+ for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
+ {
+ tim.restart();
+ for(counter = 0; counter < iter; ++counter)
+ {
+ i = boost::fusion::accumulate(
+ boost::fusion::zip(arr1, arr2), 0, poly_combine());
+ j += i;
+ }
+ run = tim.elapsed();
+ result = (std::min)(run, result);
+ }
+ std::cout << i << std::endl;
+ return result / iter;
+ }
+}
+
+int main()
+{
+ int total = 0;
+ int res;
+
+ std::cout << "short inner_product std test " << time_for_std_inner_product<8>(res) << std::endl;
+ total += res;
+ std::cout << "short inner_product fusion 2 test " << time_for_fusion_inner_product2<8>(res) << std::endl;
+ total += res;
+
+ std::cout << "medium inner_product std test " << time_for_std_inner_product<64>(res) << std::endl;
+ total += res;
+ std::cout << "medium inner_product fusion 2 test " << time_for_fusion_inner_product2<64>(res) << std::endl;
+ total += res;
+
+#if 0 // Leads to ICE with MSVC 8.0
+ std::cout << "long inner_product std test " << time_for_std_inner_product<128>(res) << std::endl;
+ total += res;
+ std::cout << "long inner_product fusion 2 test " << time_for_fusion_inner_product2<128>(res) << std::endl;
+ total += res;
+#endif
+
+ return total;
+}
diff --git a/src/boost/libs/fusion/example/performance/measure.hpp b/src/boost/libs/fusion/example/performance/measure.hpp
new file mode 100644
index 00000000..72cd71ba
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/measure.hpp
@@ -0,0 +1,85 @@
+// Copyright David Abrahams, Matthias Troyer, Michael Gauckler
+// 2005. 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)
+
+#if !defined(LIVE_CODE_TYPE)
+# define LIVE_CODE_TYPE int
+#endif
+
+#include <boost/timer.hpp>
+
+namespace test
+{
+ // This value is required to ensure that a smart compiler's dead
+ // code elimination doesn't optimize away anything we're testing.
+ // We'll use it to compute the return code of the executable to make
+ // sure it's needed.
+ LIVE_CODE_TYPE live_code;
+
+ // Call objects of the given Accumulator type repeatedly with x as
+ // an argument.
+ template <class Accumulator, class Arg>
+ void hammer(Arg const& x, long const repeats)
+ {
+ // Strategy: because the sum in an accumulator after each call
+ // depends on the previous value of the sum, the CPU's pipeline
+ // might be stalled while waiting for the previous addition to
+ // complete. Therefore, we allocate an array of accumulators,
+ // and update them in sequence, so that there's no dependency
+ // between adjacent addition operations.
+ //
+ // Additionally, if there were only one accumulator, the
+ // compiler or CPU might decide to update the value in a
+ // register rather that writing it back to memory. we want each
+ // operation to at least update the L1 cache. *** Note: This
+ // concern is specific to the particular application at which
+ // we're targeting the test. ***
+
+ // This has to be at least as large as the number of
+ // simultaneous accumulations that can be executing in the
+ // compiler pipeline. A safe number here is larger than the
+ // machine's maximum pipeline depth. If you want to test the L2
+ // or L3 cache, or main memory, you can increase the size of
+ // this array. 1024 is an upper limit on the pipeline depth of
+ // current vector machines.
+ const std::size_t number_of_accumulators = 1024;
+ live_code = 0; // reset to zero
+
+ Accumulator a[number_of_accumulators];
+
+ for (long iteration = 0; iteration < repeats; ++iteration)
+ {
+ for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
+ {
+ (*ap)(x);
+ }
+ }
+
+ // Accumulate all the partial sums to avoid dead code
+ // elimination.
+ for (Accumulator* ap = a; ap < a + number_of_accumulators; ++ap)
+ {
+ live_code += ap->sum;
+ }
+ }
+
+ // Measure the time required to hammer accumulators of the given
+ // type with the argument x.
+ template <class Accumulator, class T>
+ double measure(T const& x, long const repeats)
+ {
+ // Hammer accumulators a couple of times to ensure the
+ // instruction cache is full of our test code, and that we don't
+ // measure the cost of a page fault for accessing the data page
+ // containing the memory where the accumulators will be
+ // allocated
+ hammer<Accumulator>(x, repeats);
+ hammer<Accumulator>(x, repeats);
+
+ // Now start a timer
+ boost::timer time;
+ hammer<Accumulator>(x, repeats); // This time, we'll measure
+ return time.elapsed() / repeats; // return the time of one iteration
+ }
+}
diff --git a/src/boost/libs/fusion/example/performance/sequence_efficiency.cpp b/src/boost/libs/fusion/example/performance/sequence_efficiency.cpp
new file mode 100644
index 00000000..307ecdf3
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/sequence_efficiency.cpp
@@ -0,0 +1,248 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ 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)
+==============================================================================*/
+#include "measure.hpp"
+
+#define FUSION_MAX_LIST_SIZE 30
+#define FUSION_MAX_VECTOR_SIZE 30
+
+#include <boost/fusion/algorithm/iteration/accumulate.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/container/list.hpp>
+
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/preprocessor/enum.hpp>
+
+#include <iostream>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+// About the tests:
+//
+// The tests below compare various fusion sequences to see how abstraction
+// affects prformance.
+//
+// We have 3 sequence sizes for each fusion sequence we're going to test.
+//
+// small = 3 elements
+// medium = 10 elements
+// big = 30 elements
+//
+// The sequences are initialized with values 0..N-1 from numeric strings
+// parsed by boost::lexical_cast to make sure that the compiler is not
+// optimizing by replacing the computation with constant results computed
+// at compile time.
+//
+// These sequences will be subjected to our accumulator which calls
+// fusion::accumulate:
+//
+// this->sum += boost::fusion::accumulate(seq, 0, poly_add());
+//
+// where poly_add simply sums the current value with the content of
+// the sequence element. This accumulator will be called many times
+// through the "hammer" test (see measure.hpp).
+//
+// The tests are compared against a base using a plain_accumulator
+// which does a simple addition:
+//
+// this->sum += x;
+
+namespace
+{
+ struct poly_add
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Lhs, typename Rhs>
+ struct result<poly_add(Lhs, Rhs)>
+ : boost::remove_reference<Lhs>
+ {};
+
+ template<typename Lhs, typename Rhs>
+ Lhs operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return lhs + rhs;
+ }
+ };
+
+ // Our Accumulator function
+ template <typename T>
+ struct accumulator
+ {
+ accumulator()
+ : sum()
+ {}
+
+ template <typename Sequence>
+ void operator()(Sequence const& seq)
+ {
+ this->sum += boost::fusion::accumulate(seq, 0, poly_add());
+ }
+
+ T sum;
+ };
+
+ // Plain Accumulator function
+ template <typename T>
+ struct plain_accumulator
+ {
+ plain_accumulator()
+ : sum()
+ {}
+
+ template <typename X>
+ void operator()(X const& x)
+ {
+ this->sum += x;
+ }
+
+ T sum;
+ };
+
+ template <typename T>
+ void check(T const& seq, char const* info)
+ {
+ test::measure<accumulator<int> >(seq, 1);
+ std::cout << info << test::live_code << std::endl;
+ }
+
+ template <typename T>
+ void measure(T const& seq, char const* info, long const repeats, double base)
+ {
+ double t = test::measure<accumulator<int> >(seq, repeats);
+ std::cout
+ << info
+ << t
+ << " (" << int((t/base)*100) << "%)"
+ << std::endl;
+ }
+
+ template <typename T>
+ void test_assembler(T const& seq)
+ {
+ test::live_code = boost::fusion::accumulate(seq, 0, poly_add());
+ }
+}
+
+// We'll initialize the sequences from numeric strings that
+// pass through boost::lexical_cast to make sure that the
+// compiler is not optimizing by replacing the computation
+// with constant results computed at compile time.
+#define INIT(z, n, text) boost::lexical_cast<int>(BOOST_PP_STRINGIZE(n))
+
+int main()
+{
+ using namespace boost::fusion;
+ std::cout.setf(std::ios::scientific);
+
+ vector<
+ int, int, int
+ >
+ vsmall(BOOST_PP_ENUM(3, INIT, _));
+
+ list<
+ int, int, int
+ >
+ lsmall(BOOST_PP_ENUM(3, INIT, _));
+
+ vector<
+ int, int, int, int, int, int, int, int, int, int
+ >
+ vmedium(BOOST_PP_ENUM(10, INIT, _));
+
+ list<
+ int, int, int, int, int, int, int, int, int, int
+ >
+ lmedium(BOOST_PP_ENUM(10, INIT, _));
+
+ vector<
+ int, int, int, int, int, int, int, int, int, int
+ , int, int, int, int, int, int, int, int, int, int
+ , int, int, int, int, int, int, int, int, int, int
+ >
+ vbig(BOOST_PP_ENUM(30, INIT, _));
+
+ list<
+ int, int, int, int, int, int, int, int, int, int
+ , int, int, int, int, int, int, int, int, int, int
+ , int, int, int, int, int, int, int, int, int, int
+ >
+ lbig(BOOST_PP_ENUM(30, INIT, _));
+
+ // first decide how many repetitions to measure
+ long repeats = 100;
+ double measured = 0;
+ while (measured < 2.0 && repeats <= 10000000)
+ {
+ repeats *= 10;
+
+ boost::timer time;
+
+ test::hammer<plain_accumulator<int> >(0, repeats);
+ test::hammer<accumulator<int> >(vsmall, repeats);
+ test::hammer<accumulator<int> >(lsmall, repeats);
+ test::hammer<accumulator<int> >(vmedium, repeats);
+ test::hammer<accumulator<int> >(lmedium, repeats);
+ test::hammer<accumulator<int> >(vbig, repeats);
+ test::hammer<accumulator<int> >(lbig, repeats);
+
+ measured = time.elapsed();
+ }
+
+ test::measure<plain_accumulator<int> >(1, 1);
+ std::cout
+ << "base accumulated result: "
+ << test::live_code
+ << std::endl;
+
+ double base_time = test::measure<plain_accumulator<int> >(1, repeats);
+ std::cout
+ << "base time: "
+ << base_time;
+
+ std::cout
+ << std::endl
+ << "-------------------------------------------------------------------"
+ << std::endl;
+
+ check(vsmall, "small vector accumulated result: ");
+ check(lsmall, "small list accumulated result: ");
+ check(vmedium, "medium vector accumulated result: ");
+ check(lmedium, "medium list accumulated result: ");
+ check(vbig, "big vector accumulated result: ");
+ check(lbig, "big list accumulated result: ");
+
+ std::cout
+ << "-------------------------------------------------------------------"
+ << std::endl;
+
+ measure(vsmall, "small vector time: ", repeats, base_time);
+ measure(lsmall, "small list time: ", repeats, base_time);
+ measure(vmedium, "medium vector time: ", repeats, base_time);
+ measure(lmedium, "medium list time: ", repeats, base_time);
+ measure(vbig, "big vector time: ", repeats, base_time);
+ measure(lbig, "big list time: ", repeats, base_time);
+
+ std::cout
+ << "-------------------------------------------------------------------"
+ << std::endl;
+
+ // Let's see how this looks in assembler
+ test_assembler(vmedium);
+
+ // This is ultimately responsible for preventing all the test code
+ // from being optimized away. Change this to return 0 and you
+ // unplug the whole test's life support system.
+ return test::live_code != 0;
+}
diff --git a/src/boost/libs/fusion/example/performance/timings.txt b/src/boost/libs/fusion/example/performance/timings.txt
new file mode 100644
index 00000000..35549170
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/timings.txt
@@ -0,0 +1,57 @@
+===============================================================================
+Copyright (C) 2001-2007 Joel de Guzman, Dan Marsden, Tobias Schwinger
+
+Use, modification and distribution is subject to 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)
+===============================================================================
+
+Timing result for sequence_efficiency.cpp comparing the speed of various
+fusion sequences. The test involves accumulating the elements of the
+sequence which is primed to have values 0..N (N=size of sequence). Small,
+medium and big sequences are tested where:
+
+ small = 3 elements
+ medium = 10 elements
+ big = 30 elements
+
+Tester: Joel de Guzman. WinXP, P4-3.0GHZ, 2GB RAM
+
+VC7.1 (flags = /MD /O2 /EHsc /GS)
+
+ small vector time: 1.870000e-006
+ small list time: 1.870000e-006
+ medium vector time: 1.880000e-006
+ medium list time: 3.600000e-006
+ big vector time: 2.030000e-006
+ big list time: 8.910000e-006
+
+VC8.0 (flags = /MD /O2 /EHsc /GS)
+
+ small vector time: 2.500000e-05
+ small list time: 2.500000e-05
+ medium vector time: 7.810000e-05
+ medium list time: 7.810000e-05
+ big vector time: 2.469000e-04
+ big list time: 2.453000e-04
+
+G++ 3.4 (flags = -ftemplate-depth-128 -funroll-loops -O3 -finline-functions -Wno-inline -Wall)
+
+ small vector time: 2.500000e-05
+ small list time: 2.500000e-05
+ medium vector time: 7.970000e-05
+ medium list time: 7.970000e-05
+ big vector time: 2.516000e-04
+ big list time: 2.485000e-04
+
+Intel 9.1 (flags = /MD /O2 /EHsc /GS)
+
+ small vector time: 1.125000e-006
+ small list time: 1.125000e-006
+ medium vector time: 1.125000e-006
+ medium list time: 1.141000e-006
+ big vector time: 1.140000e-006
+ big list time: 1.141000e-006
+
+
+
diff --git a/src/boost/libs/fusion/example/performance/zip_efficiency.cpp b/src/boost/libs/fusion/example/performance/zip_efficiency.cpp
new file mode 100644
index 00000000..6d240f2c
--- /dev/null
+++ b/src/boost/libs/fusion/example/performance/zip_efficiency.cpp
@@ -0,0 +1,155 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ 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)
+==============================================================================*/
+#include "measure.hpp"
+
+//~ #define FUSION_MAX_VECTOR_SIZE 30
+
+#include <boost/fusion/algorithm/iteration/accumulate.hpp>
+#include <boost/fusion/algorithm/transformation/zip.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/sequence/intrinsic/value_at.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <iostream>
+
+#ifdef _MSC_VER
+// inline aggressively
+# pragma inline_recursion(on) // turn on inline recursion
+# pragma inline_depth(255) // max inline depth
+#endif
+
+namespace
+{
+ struct zip_add
+ {
+ template<typename Lhs, typename Rhs>
+ struct result
+ {
+ typedef typename
+ boost::remove_reference<
+ typename boost::fusion::result_of::value_at_c<Lhs, 0>::type
+ >::type
+ type;
+ };
+
+ template<typename Lhs, typename Rhs>
+ typename result<Lhs, Rhs>::type
+ operator()(const Lhs& lhs, const Rhs& rhs) const
+ {
+ return boost::fusion::at_c<0>(lhs) + boost::fusion::at_c<1>(lhs) + rhs;
+ }
+ };
+
+ // Our Accumulator function
+ template <typename T>
+ struct zip_accumulator
+ {
+ zip_accumulator()
+ : sum()
+ {}
+
+ template <typename Sequence>
+ void operator()(Sequence const& seq)
+ {
+ this->sum += boost::fusion::accumulate(seq, 0, zip_add());
+ }
+
+ T sum;
+ };
+
+ template <typename T>
+ void check(T const& seq, char const* info)
+ {
+ test::measure<zip_accumulator<int> >(seq, 1);
+ std::cout << info << test::live_code << std::endl;
+ }
+
+ template <typename T>
+ void measure(T const& seq, char const* info, long const repeats)
+ {
+ std::cout
+ << info
+ << test::measure<zip_accumulator<int> >(seq, repeats)
+ << std::endl;
+ }
+}
+
+int main()
+{
+ using namespace boost::fusion;
+
+ std::cout.setf(std::ios::scientific);
+
+ vector<
+ int, int, int
+ >
+ vsmall_1(BOOST_PP_ENUM_PARAMS(3,));
+
+ vector<
+ int, int, int
+ >
+ vsmall_2(BOOST_PP_ENUM_PARAMS(3,));
+
+ vector<
+ int, int, int, int, int, int, int, int, int, int
+ >
+ vmedium_1(BOOST_PP_ENUM_PARAMS(10,));
+
+ vector<
+ int, int, int, int, int, int, int, int, int, int
+ >
+ vmedium_2(BOOST_PP_ENUM_PARAMS(10,));
+
+ //~ vector<
+ //~ int, int, int, int, int, int, int, int, int, int
+ //~ , int, int, int, int, int, int, int, int, int, int
+ //~ , int, int, int, int, int, int, int, int, int, int
+ //~ >
+ //~ vbig_1(BOOST_PP_ENUM_PARAMS(30,));
+
+ //~ vector<
+ //~ int, int, int, int, int, int, int, int, int, int
+ //~ , int, int, int, int, int, int, int, int, int, int
+ //~ , int, int, int, int, int, int, int, int, int, int
+ //~ >
+ //~ vbig_2(BOOST_PP_ENUM_PARAMS(30,));
+
+ // first decide how many repetitions to measure
+ long repeats = 100;
+ double measured = 0;
+ while (measured < 2.0 && repeats <= 10000000)
+ {
+ repeats *= 10;
+
+ boost::timer time;
+
+ test::hammer<zip_accumulator<int> >(zip(vsmall_1, vsmall_2), repeats);
+ test::hammer<zip_accumulator<int> >(zip(vmedium_1, vmedium_2), repeats);
+ //~ test::hammer<zip_accumulator<int> >(zip(vbig_1, vbig_2), repeats);
+
+ measured = time.elapsed();
+ }
+
+ check(zip(vsmall_1, vsmall_2),
+ "small zip accumulated result: ");
+ check(zip(vmedium_1, vmedium_2),
+ "medium zip accumulated result: ");
+ //~ check(zip(vbig_1, vbig_2),
+ //~ "big zip accumulated result: ");
+
+ measure(zip(vsmall_1, vsmall_2),
+ "small zip time: ", repeats);
+ measure(zip(vmedium_1, vmedium_2),
+ "medium zip time: ", repeats);
+ //~ measure(zip(vbig_1, vbig_2),
+ //~ "big zip time: ", repeats);
+
+ // This is ultimately responsible for preventing all the test code
+ // from being optimized away. Change this to return 0 and you
+ // unplug the whole test's life support system.
+ return test::live_code != 0;
+}