$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: steven_at_[hidden]
Date: 2008-02-12 18:45:33
Author: steven_watanabe
Date: 2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
New Revision: 43228
URL: http://svn.boost.org/trac/boost/changeset/43228
Log:
Initial version of new interface
Added:
   sandbox/switch/libs/switch/alternate/
   sandbox/switch/libs/switch/alternate/switch/
   sandbox/switch/libs/switch/alternate/switch/Jamfile.v2   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/binary_search.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/case.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/fusion.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/if_else.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/map.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/sorted_array.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/switch.hpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/test_case.cpp   (contents, props changed)
   sandbox/switch/libs/switch/alternate/switch/test_speed.cpp   (contents, props changed)
Added: sandbox/switch/libs/switch/alternate/switch/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/Jamfile.v2	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,22 @@
+# Switch
+#
+# Copyright (c) 2007-2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt
+
+import testing ;
+
+project switch_test : :
+    requirements <include>../../.. <include>$(BOOST_ROOT) <warnings>all
+;
+
+
+{
+  test-suite switch_:
+   :
+    [ run test_case.cpp $(BOOST_ROOT)/libs/test/build//boost_unit_test_framework : : : : ]
+   ;
+}
Added: sandbox/switch/libs/switch/alternate/switch/binary_search.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/binary_search.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,219 @@
+// binary_search.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distriuted 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_SWITCH_BINARY_SEARCH_HPP_INCLUDED
+#define BOOST_SWITCH_BINARY_SEARCH_HPP_INCLUDED
+
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/deref.hpp>
+
+namespace boost {
+
+namespace binary_search_switch {
+
+template<int N>
+struct list_at {
+    template<class L>
+    struct apply {
+        typedef typename list_at<N - 1>::template apply<L>::type::tail type;
+    };
+};
+
+template<>
+struct list_at<0> {
+    template<class L>
+    struct apply {
+        typedef L type;
+    };
+};
+
+struct list_end {};
+
+template<class T, class Tail>
+struct list {
+    typedef T element;
+    typedef Tail tail;
+};
+
+template<class List, class T>
+struct insert;
+
+template<bool>
+struct insert_impl;
+
+template<>
+struct insert_impl<true> {
+    template<class List, class T>
+    struct apply {
+        typedef list<T, List> type;
+    };
+};
+
+template<>
+struct insert_impl<false> {
+    template<class List, class T>
+    struct apply {
+        typedef list<typename List::element, typename insert<typename List::tail, T>::type> type;
+    };
+};
+
+template<class List, class T>
+struct insert {
+    typedef typename insert_impl<(T::value) < (List::element::value)>::template apply<List, T>::type type;
+};
+
+template<class T>
+struct insert<list_end, T> {
+    typedef list<T, list_end> type;
+};
+
+template<int Low, int High, class S, int Diff = (High - Low)>
+struct switch_impl {
+    static const int mid = Low + Diff / 2;
+    typedef typename list_at<mid>::template apply<S>::type::element mid_t;
+    template<class R, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        if(mid_t::value < i) {
+            return(switch_impl<mid, High, S>::template apply<R>(i, f, d));
+        } else {
+            return(switch_impl<Low, mid, S>::template apply<R>(i, f, d));
+        }
+    }
+};
+
+template<int Low, int High, class S>
+struct switch_impl<Low, High, S, 0> {
+    template<class R, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        return(d(i));
+    }
+};
+
+template<int Low, int High, class S>
+struct switch_impl<Low, High, S, 2> {
+    typedef typename list_at<Low>::template apply<S>::type::element first_t;
+    typedef typename list_at<Low + 1>::template apply<S>::type::element second_t;
+    template<class R, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        if(first_t::value == i) {
+            return(f.template apply<R>(first_t()));
+        } else if(second_t::value == i) {
+            return(f.template apply<R>(second_t()));
+        } else {
+            return(d(i));
+        }
+    }
+};
+
+template<int Low, int High, class S>
+struct switch_impl<Low, High, S, 1> {
+    typedef typename list_at<Low>::template apply<S>::type::element mid_t;
+    template<class R, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        if(mid_t::value == i) {
+            return(f.template apply<R>(mid_t()));
+        } else {
+            return(d(i));
+        }
+    }
+};
+
+template<int Low, int High, class S>
+struct switch_impl<Low, High, S, 3> {
+    static const int mid = Low + 1;
+    typedef typename list_at<mid>::template apply<S>::type::element mid_t;
+    template<class R, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        if(mid_t::value < i) {
+            return(switch_impl<mid + 1, High, S>::template apply<R>(i, f, d));
+        } else if(mid_t::value > i) {
+            return(switch_impl<Low, mid, S>::template apply<R>(i, f, d));
+        } else {
+            return(f.template apply<R>(mid_t()));
+        }
+    }
+};
+
+template<int N>
+struct sort {
+    template<class Iter>
+    struct apply {
+        typedef typename mpl::next<Iter>::type next1;
+        typedef typename mpl::next<next1>::type next2;
+        typedef typename mpl::next<next2>::type next3;
+        typedef typename mpl::next<next3>::type next4;
+        typedef typename insert<
+                typename insert<
+                typename insert<
+                typename insert<typename sort<N - 4>::template apply<next4>::type,
+                typename mpl::deref<next3>::type>::type,
+                typename mpl::deref<next2>::type>::type,
+                typename mpl::deref<next1>::type>::type,
+                typename mpl::deref<Iter>::type>::type
+            type;
+    };
+};
+
+template<>
+struct sort<0> {
+    template<class Iter>
+    struct apply {
+        typedef list_end type;
+    };
+};
+
+template<>
+struct sort<1> {
+    template<class Iter>
+    struct apply {
+        typedef list<typename mpl::deref<Iter>::type, list_end> type;
+    };
+};
+
+template<>
+struct sort<2> {
+    template<class Iter>
+    struct apply {
+        typedef typename mpl::next<Iter>::type next1;
+        typedef typename insert<
+                list<typename mpl::deref<next1>::type, list_end>,
+                typename mpl::deref<Iter>::type>::type
+            type;
+    };
+};
+
+template<>
+struct sort<3> {
+    template<class Iter>
+    struct apply {
+        typedef typename mpl::next<Iter>::type next1;
+        typedef typename mpl::next<next1>::type next2;
+        typedef typename insert<
+                typename insert<
+                list<typename mpl::deref<next2>::type, list_end>,
+                typename mpl::deref<next1>::type>::type,
+                typename mpl::deref<Iter>::type>::type
+            type;
+    };
+};
+
+template<class R, class I, class F, class D>
+R switch_(I i, const F& f, D d) {
+    typedef switch_impl<0, mpl::size<typename F::labels>::value,
+        typename sort<mpl::size<typename F::labels>::value>::template apply<typename mpl::begin<typename F::labels>::type>::type> impl;
+    return(impl::template apply<R>(i, f, d));
+}
+
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/case.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/case.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,178 @@
+// case.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_SWITCH_CASE_HPP_INCLUDED
+#define BOOST_SWITCH_CASE_HPP_INCLUDED
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/vector/vector50.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/fold.hpp>
+
+namespace boost {
+
+namespace switch_detail {
+
+struct empty_set {
+    template<class T>
+    static char lookup(T);
+};
+
+template<class Base, class T>
+struct set : Base {
+    static char (&lookup(T))[2];
+    using Base::lookup;
+    typedef set type;
+};
+
+template<class S>
+struct make_set {
+    typedef typename mpl::fold<S, empty_set, set<mpl::_, mpl::_> >::type type;
+};
+
+template<class S, class N>
+struct contains_impl {
+    typedef typename switch_detail::make_set<S>::type as_set;
+    static const bool value = (sizeof(as_set::lookup(N())) != 1);
+};
+
+}
+
+template<class Case>
+class restrict_case_t {
+public:
+    template<class T>
+    explicit restrict_case_t(T& t) : impl(t) {}
+    typedef typename Case::labels labels;
+    template<class R, class N>
+    typename boost::enable_if_c<
+        switch_detail::contains_impl<typename Case::labels, N>::value,
+        R
+    >::type apply(N n) const {
+        return(impl.template apply<R>(n));
+    }
+private:
+    Case impl;
+};
+
+template<class Case1, class Case2>
+class binary_case_t : public Case1, public Case2 {
+public:
+    template<class T>
+    explicit binary_case_t(const T& t) : Case1(t), Case2(t) {}
+    binary_case_t(const Case1& case1, const Case2& case2) :
+        Case1(case1),
+        Case2(case2) {}
+    // msvc does not like mpl::joint_view
+    typedef typename mpl::copy<
+        typename Case2::labels,
+        mpl::back_inserter<typename Case1::labels>
+    >::type labels;
+    using Case1::apply;
+    using Case2::apply;
+};
+
+template<class N, class F>
+class single_case_t {
+public:
+    single_case_t(F f) : impl(f) {}
+    typedef mpl::vector1<N> labels;
+    template<class R>
+    R apply(N n) const {
+        return(impl(n));
+    }
+private:
+    F impl;
+};
+
+template<class S, class F>
+class case_group_t {
+public:
+    case_group_t(F f) : impl(f) {}
+    typedef S labels;
+    template<class R, class N>
+    R apply(N n) const {
+        return(impl(n));
+    }
+private:
+    F impl;
+};
+
+template<class F>
+struct add_to_group {
+    template<class Prev, class Current>
+    struct apply {
+        typedef binary_case_t<Prev, single_case_t<Current, F> > type;
+    };
+};
+
+class empty_case {
+public:
+    template<class T>
+    explicit empty_case(T&) {}
+    typedef mpl::vector0<> labels;
+    void apply();
+};
+
+template<class S, class F>
+struct make_case_group {
+    typedef typename mpl::fold<S, empty_case, add_to_group<F> >::type type;
+};
+
+template<class Case>
+class expression_template_case_t {
+public:
+    typedef typename Case::labels labels;
+    template<class T>
+    explicit expression_template_case_t(T& t) : impl(t) {}
+    template<class T0, class T1>
+    expression_template_case_t(T0& t0, T1& t1) : impl(t0, t1) {}
+    template<class R, class N>
+    R apply(N n) const {
+        return(impl.template apply<R>(n));
+    }
+    Case& get() { return(impl); }
+    const Case& get() const { return(impl); }
+private:
+    Case impl;
+};
+
+template<class Case>
+expression_template_case_t<restrict_case_t<Case> > restrict_case(Case& c) {
+    return(expression_template_case_t<restrict_case_t<Case> >(c));
+}
+
+template<class Case1, class Case2>
+expression_template_case_t<binary_case_t<Case1, Case2> >
+operator,(const expression_template_case_t<Case1>& c1,
+          const expression_template_case_t<Case2>& c2) {
+    return(expression_template_case_t<binary_case_t<Case1, Case2> >(
+        c1.get(), c2.get()));
+}
+
+template<class S, class F>
+expression_template_case_t<restrict_case_t<case_group_t<S,F> > > case_(F f) {
+ return(expression_template_case_t<restrict_case_t<case_group_t<S,F> > >(f));
+}
+
+//template<class S, class F>
+//expression_template_case_t<typename make_case_group<S, F>::type> case_(F f) {
+//    return(expression_template_case_t<typename make_case_group<S,F>::type>(f));
+//}
+
+template<int N, class F>
+expression_template_case_t<single_case_t<mpl::int_<N>, F> > case_c(F f) {
+    return(expression_template_case_t<single_case_t<mpl::int_<N>, F> >(f));
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/fusion.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/fusion.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,207 @@
+// fusion.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distriuted 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_SWITCH_FUSION_HPP_INCLUDED
+#define BOOST_SWITCH_FUSION_HPP_INCLUDED
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+namespace boost {
+
+template<class S>
+class fusion_case_t;
+
+namespace switch_detail {
+
+template<int N>
+struct get_nth {
+    template<class Iter>
+    struct apply {
+        typedef typename boost::fusion::result_of::next<
+            typename get_nth<N - 1>::template apply<Iter>::type
+        >::type type;
+        static type call(const Iter& iter) {
+            return(boost::fusion::next(
+                get_nth<N - 1>::template apply<Iter>::call(iter)));
+        }
+    };
+};
+
+template<>
+struct get_nth<0> {
+    template<class Iter>
+    struct apply {
+        typedef Iter type;
+        static Iter call(const Iter& iter) {
+            return(iter);
+        }
+    };
+};
+
+template<class T, class R>
+struct internal_at;
+
+template<class T>
+struct internal_size;
+
+template<class T, class R>
+struct internal_at<fusion_case_t<T>, R> {
+    template<int N>
+    struct apply {
+        typedef typename boost::remove_cv<
+            typename boost::remove_reference<
+                typename boost::fusion::result_of::deref<
+                    typename get_nth<N>::template apply<
+                        typename boost::fusion::result_of::begin<S>::type
+                    >::type
+                >::type
+            >::type
+        >::type f_type;
+        typedef typename f_type::label label;
+        static R call(const fusion_case_t<T>& t) {
+            return(boost::fusion::deref(get_nth<N>::template apply<
+                typename boost::fusion::result_of::begin<S>::type
+            >::call(boost::fusion::begin(t.get_seq())))());
+        }
+        static bool fallthrough() { return(f_type::fallthrough()); }
+    };
+};
+
+template<class T>
+struct internal_size<fusion_case_t<T> > : boost::fusion::result_of::size<T> {};
+
+struct fusion_case_tag {};
+
+template<class It, class End>
+struct fusion_case_iterator {
+    typedef typename boost::remove_cv<
+        typename boost::remove_reference<
+            typename boost::fusion::result_of_deref<It>::type
+        >::type
+    >::type::label type;
+    typedef typename fusion_case_iterator<
+        typename boost::fusion::result_of::next<It>::type, End
+    > next;
+};
+
+template<class End>
+struct fusion_case_iterator<End, End> {};
+
+template<class T>
+struct wrap {};
+
+struct int_map_base {
+    static void lookup();
+};
+
+template<class Key, int Value, class Base>
+struct int_map : Base {
+    static char (&lookup(wrap<Key>))[Value + 1];
+    using Base::lookup;
+};
+
+template<int N>
+struct make_index_map {
+    template<class T, int I>
+    struct apply {
+        typedef int_map<typename mpl::deref<T>::type, I,
+            typename make_index_map<N - 1>::template apply<
+                typename mpl::next<T>::type, I + 1
+            >::type
+        > type;
+    };
+};
+
+template<>
+struct make_index_map<0> {
+    template<class T, int I>
+    struct apply {
+        typedef int_map_base type;
+    };
+};
+
+}
+
+template<class S>
+class fusion_case_t {
+public:
+    struct labels {
+        typedef fusion_case_tag tag;
+        typedef labels type;
+        typedef S impl;
+    };
+    fusion_case_t(S& sequence) : s(sequence) {}
+    S& get_seq() const { return(s); }
+    template<class R, class N>
+    R apply(N) {
+        typedef typename make_index_map<
+            mpl::size<labels>::value
+        >::template apply<typename mpl::begin<labels>::type, 0>::type map;
+        return(switch_detail::internal_at<fusion_case_t, R>::template apply<
+            sizeof(map::lookup(wrap<N>())) - 1
+        >::call());
+    }
+private:
+    S& s;
+};
+
+template<class S>
+fusion_case_t<S> fusion_case(S& s) {
+    return(fusion_case_t<S>(s));
+}
+
+template<class S>
+fusion_case_t<const S> fusion_case(const S& s) {
+    return(fusion_case_t<const S>(s));
+}
+
+namespace mpl {
+
+template<>
+struct size_impl<boost::switch_detail::fusion_case_tag> {
+    template<class T>
+    struct apply : boost::fusion::result_of::size<typename T::impl> {};
+};
+
+template<>
+struct begin_impl<boost::switch_detail::fusion_case_tag> {
+    template<class T>
+    struct apply {
+        typedef boost::switch_detail::fusion_case_iterator<
+            typename boost::fusion::result_of::begin<typename T::impl>::type,
+            typename boost::fusion::result_of::end<typename T::impl>::type
+        > type;
+    };
+};
+
+template<>
+struct end_impl<boost::switch_detail::fusion_case_tag> {
+    template<class T>
+    struct apply {
+        typedef boost::switch_detail::fusion_case_iterator<
+            typename boost::fusion::result_of::end<typename T::impl>::type,
+            typename boost::fusion::result_of::end<typename T::impl>::type
+        > type;
+    };
+};
+
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/if_else.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/if_else.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,53 @@
+// if_else.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distriuted 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_SWITCH_IF_ELSE_HPP_INCLUDED
+#define BOOST_SWITCH_IF_ELSE_HPP_INCLUDED
+
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/next.hpp>
+
+namespace boost {
+
+namespace if_else_switch {
+
+template<int N>
+struct switch_impl {
+    template<class R, class Iter, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        if(mpl::deref<Iter>::type::value == i) {
+            typename mpl::deref<Iter>::type x;
+            return(f.template apply<R>(x));
+        } else {
+            return(switch_impl<N - 1>::template apply<R, typename mpl::next<Iter>::type>(i, f, d));
+        }
+    }
+};
+
+template<>
+struct switch_impl<0> {
+    template<class R, class Iter, class I, class F, class D>
+    static R apply(I i, F& f, D& d) {
+        return(d(i));
+    }
+};
+
+template<class R, class I, class F, class D>
+R switch_(I i, const F& f, D d) {
+    typedef switch_impl<mpl::size<typename F::labels>::value> impl;
+    return(impl::template apply<R, typename mpl::begin<typename F::labels>::type>(i, f, d));
+};
+
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/map.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/map.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,74 @@
+// map.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_SWITCH_MAP_HPP_INCLUDED
+#define BOOST_SWITCH_MAP_HPP_INCLUDED
+
+#include <map>
+//#include <boost/thread/once.hpp>
+#include <boost/mpl/for_each.hpp>
+
+namespace boost {
+
+namespace map_switch {
+
+template<class R, class I, class F>
+struct switch_impl {
+    static std::map<I, R(*)(const F&)>* impl;
+    //static boost::once_flag init_flag;
+    struct init_impl {
+        init_impl() {
+            init();
+        }
+    };
+    static const std::map<I, R(*)(const F&)>& get() {
+        //boost::call_once(&init, init_flag);
+        static init_impl initialize;
+        return(*impl);
+    }
+    static void init() {
+        impl = new std::map<I, R(*)(const F&)>();
+        boost::mpl::for_each<typename F::labels>(do_init());
+    }
+    struct do_init {
+        template<class T>
+        void operator()(T) {
+            impl->insert(std::make_pair(static_cast<I>(T::value), &f_impl<T>::call));
+        }
+    };
+    template<class T>
+    struct f_impl {
+        static R call(const F& f) {
+            return(f.template apply<R>(T()));
+        }
+    };
+};
+
+template<class R, class I, class F>
+std::map<I, R(*)(const F&)>* switch_impl<R, I, F>::impl;
+//template<class R, class I, class F>
+//boost::once_flag switch_impl<R, I, F>::init_flag = BOOST_ONCE_INIT;
+
+template<class R, class I, class F, class Default>
+R switch_(I i, const F& f, Default default_) {
+    const std::map<I, R(*)(const F&)>& m = switch_impl<R, I, F>::get();
+    typename std::map<I, R(*)(const F&)>::const_iterator iter = m.find(i);
+    if(iter == m.end()) {
+        return(default_(i));
+    } else {
+        return(iter->second(f));
+    }
+}
+
+
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/sorted_array.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/sorted_array.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,96 @@
+// map.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_SWITCH_SORTED_ARRAY_HPP_INCLUDED
+#define BOOST_SWITCH_SORTED_ARRAY_HPP_INCLUDED
+
+#include <algorithm>
+//#include <boost/thread/once.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/range_c.hpp>
+
+namespace boost {
+
+namespace sorted_array_switch {
+
+// requires that K and V are POD
+template<class K, class V>
+struct map_element {
+    K k;
+    V v;
+    bool operator<(const map_element& other) const {
+        return(k < other.k);
+    }
+    bool operator<(const K& other) const {
+        return(k < other);
+    }
+    friend bool operator<(const K& other, const map_element& self) {
+        return(other < self.k);
+    }
+};
+
+template<class R, class I, class F>
+struct switch_impl {
+    static map_element<I, R(*)(const F&)> impl[mpl::size<typename F::labels>::value];
+    //static boost::once_flag init_flag;
+    struct init_impl {
+        init_impl() {
+            init();
+        }
+    };
+    static R (*get(I i))(const F&) {
+        //boost::call_once(&init, init_flag);
+        static init_impl initialize;
+        map_element<I, R(*)(const F&)>* result = std::lower_bound(&impl[0], &impl[0] + mpl::size<typename F::labels>::value, i);
+        if(result == &impl[0] + mpl::size<typename F::labels>::value || result->k != i) {
+            return(0);
+        } else {
+            return(result->v);
+        }
+    }
+    static void init() {
+        boost::mpl::for_each<mpl::range_c<int, 0, mpl::size<typename F::labels>::value> >(do_init());
+        std::sort(&impl[0], &impl[0] + mpl::size<typename F::labels>::value);
+    }
+    struct do_init {
+        template<class T>
+        void operator()(T) {
+            impl[T::value].k = static_cast<I>(mpl::at_c<typename F::labels, T::value>::type::value);
+            impl[T::value].v = &f_impl<typename mpl::at_c<typename F::labels, T::value>::type>::call;
+        }
+    };
+    template<class T>
+    struct f_impl {
+        static R call(const F& f) {
+            return(f.template apply<R>(T()));
+        }
+    };
+};
+
+template<class R, class I, class F>
+map_element<I, R(*)(const F&)> switch_impl<R, I, F>::impl[mpl::size<typename F::labels>::value];
+//template<class R, class I, class F>
+//boost::once_flag switch_impl<R, I, F>::init_flag = BOOST_ONCE_INIT;
+
+template<class R, class I, class F, class Default>
+R switch_(I i, const F& f, Default default_) {
+    R (*impl)(const F&) = switch_impl<R, I, F>::get(i);
+    if(impl == 0) {
+        return(default_(i));
+    } else {
+        return(impl(f));
+    }
+}
+
+
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/switch.hpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/switch.hpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,128 @@
+// switch.hpp
+//
+// Copyright (c) 2006-2008
+// Steven Watanabe
+//
+// Distriuted 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_SWITCH_SWITCH_HPP_INCLUDED
+#define BOOST_SWITCH_SWITCH_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/preprocessor/config/limits.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+
+#ifndef BOOST_SWITCH_LIMIT
+    #define BOOST_SWITCH_LIMIT 50
+#endif
+
+#if BOOST_SWITCH_LIMIT > BOOST_PP_LIMIT_REPEAT
+    #error BOOST_SWITCH_LIMIT exceeds Boost.Preprocessor limit
+#endif
+#if BOOST_SWITCH_LIMIT > BOOST_PP_LIMIT_ITERATION
+    #error BOOST_SWITCH_LIMIT exceeds Boost.Preprocessor limit
+#endif
+
+namespace boost {
+
+namespace switch_detail {
+
+// Avoid the need to create all the specializations of switch_impl
+// twice. Just pass this to switch_impl<N>::apply(...) when no
+// default is supplied.
+
+template<class R>
+struct default_construct {
+    template<class Int>
+    R operator()(Int i) const {
+        return(R());
+    }
+};
+
+// N is the number of cases not including the default
+template<int N>
+struct switch_impl;
+
+// specialize for 0 separately to avoid warnings
+template<>
+struct switch_impl<0> {
+    template<class R, class Int, class S, class Default>
+    static R
+    apply(Int i, S&, Default d BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(R)) {
+        return(d(i));
+    }
+};
+
+template<class R, class L, class T>
+R do_call(T& t) {
+    return(t.template apply<R>(L()));
+}
+
+template<class T, class R>
+struct internal_at {
+    template<int N>
+    struct apply {
+        typedef typename mpl::at_c<typename T::labels, N>::type label;
+        static R call(T& t) {
+            return(do_call<R, label>(t));
+        }
+        static bool fallthrough() { return(false); }
+    };
+};
+
+template<class T>
+struct size : mpl::size<typename T::labels> {};
+
+#define BOOST_SWITCH_CASE(z, n, data)           \
+    {                                           \
+    typedef typename impl::template apply<n> c; \
+    case c::label::value:                       \
+        if(!c::fallthrough())                   \
+            return(c::call(s));                 \
+        else c::call(s);                        \
+    }
+
+#define BOOST_SWITCH_IMPL(z, n, data)                                   \
+    template<>                                                          \
+    struct switch_impl<n> {                                             \
+        template<class R, class I, class S, class D>                    \
+        static R                                                        \
+        apply(I i, S& s, D d BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(R)) {  \
+            typedef internal_at<S, R> impl;                             \
+            switch(i) {                                                 \
+                BOOST_PP_REPEAT_##z(n, BOOST_SWITCH_CASE, ~)            \
+                default: return(d(i));                                  \
+            }                                                           \
+        }                                                               \
+    };
+
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_SWITCH_LIMIT)
+#define BOOST_PP_LOCAL_MACRO(n) BOOST_SWITCH_IMPL(1, n, ~)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#undef BOOST_SWITCH_IMPL
+#undef BOOST_SWITCH_CASE
+
+}
+
+template<class R, class N, class S>
+inline R switch_(N n, S s BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(R)) {
+    typedef switch_detail::switch_impl<switch_detail::size<S>::value> impl;
+    switch_detail::default_construct<R> default_;
+    return(impl::template apply<R>(n, s, default_));
+}
+
+template<class R, class N, class S, class D>
+inline R switch_(N n, S s, D d BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(R)) {
+    typedef switch_detail::switch_impl<switch_detail::size<S>::value> impl;
+    return(impl::template apply<R>(n, s, d));
+}
+
+}
+
+#endif
Added: sandbox/switch/libs/switch/alternate/switch/test_case.cpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/test_case.cpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,45 @@
+// test_case.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_AUTO_TEST_MAIN
+
+#include "switch.hpp"
+#include "case.hpp"
+
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/vector_c.hpp>
+
+#include <boost/test/auto_unit_test.hpp>
+
+namespace {
+    struct f {
+        typedef int result_type;
+        template<class T>
+        int operator()(T) const {
+            return(T::value * T::value);
+        }
+    };
+}
+
+BOOST_AUTO_TEST_CASE(test1) {
+    using boost::case_;
+    BOOST_CHECK_EQUAL(boost::switch_<int>(2, (case_<boost::mpl::range_c<int, 0, 5> >(f()))), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test2) {
+    using boost::case_;
+    BOOST_CHECK_EQUAL(boost::switch_<int>(2,
+        (case_<boost::mpl::vector_c<int, 0> >(f()),
+        case_<boost::mpl::vector_c<int, 1> >(f()),
+        case_<boost::mpl::vector_c<int, 2> >(f()),
+        case_<boost::mpl::vector_c<int, 3> >(f()),
+        case_<boost::mpl::vector_c<int, 4> >(f()),
+        case_<boost::mpl::vector_c<int, 5> >(f()))
+        ), 4);
+}
Added: sandbox/switch/libs/switch/alternate/switch/test_speed.cpp
==============================================================================
--- (empty file)
+++ sandbox/switch/libs/switch/alternate/switch/test_speed.cpp	2008-02-12 18:45:32 EST (Tue, 12 Feb 2008)
@@ -0,0 +1,123 @@
+// test_speed.hpp
+//
+// Copyright (c) 2008
+// Steven Watanabe
+//
+// Distriuted 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)
+
+#define BOOST_SWITCH_LIMIT 250
+
+#pragma warning(disable:4307)
+
+#include "if_else.hpp"
+#include "binary_search.hpp"
+#include "switch.hpp"
+#include "map.hpp"
+#include "sorted_array.hpp"
+#include "case.hpp"
+
+#include <iostream>
+
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/transform_view.hpp>
+#include <boost/timer.hpp>
+
+#include <boost/preprocessor/repetition/enum.hpp>
+
+struct test_function {
+    template<class N>
+    int operator()(N) const {
+        return(N::value * N::value);
+    }
+};
+
+struct default_ {
+    int operator()(int) {
+        return(-1);
+    }
+};
+
+int x;
+
+#define CASE(z, n, data) boost::case_c<n * n>(data)
+
+struct square {
+    template<class T>
+    struct apply {
+        typedef boost::mpl::int_<T::value * T::value> type;
+    };
+};
+
+template<class F>
+void do_test(const char* name, F f) {
+
+    std::cout << name << ":\n";
+
+    {
+        boost::timer timer;
+
+        for(int i = 0; i < 100000000; ++i) {
+            x = f(i * 13 % BOOST_SWITCH_LIMIT, boost::case_<boost::mpl::range_c<int, 0, BOOST_SWITCH_LIMIT> >(test_function()), default_());
+        }
+
+        std::cout << "consecutive: " << timer.elapsed() << std::endl;
+    }
+
+    {
+        boost::timer timer;
+
+        for(int i = 0; i < 100000000; ++i) {
+            x = f((i * 13 % BOOST_SWITCH_LIMIT) * (i * 13 % BOOST_SWITCH_LIMIT), boost::case_<boost::mpl::transform_view<boost::mpl::range_c<int, 0, BOOST_SWITCH_LIMIT>, square> >(test_function()), default_());
+            //x = f((i % BOOST_SWITCH_LIMIT) * (i % BOOST_SWITCH_LIMIT), (BOOST_PP_ENUM(BOOST_SWITCH_LIMIT, CASE, test_function())), default_());
+        }
+
+        std::cout << "spread out: " << timer.elapsed() << std::endl;
+
+    }
+
+}
+
+struct test_switch {
+    template<class I, class Case, class Default>
+    int operator()(I i, const Case& case_, const Default& default_) {
+        return(boost::switch_<int>(i, case_, default_));
+    }
+};
+
+struct test_if_else {
+    template<class I, class Case, class Default>
+    int operator()(I i, const Case& case_, const Default& default_) {
+        return(boost::if_else_switch::switch_<int>(i, case_, default_));
+    }
+};
+
+struct test_binary_search {
+    template<class I, class Case, class Default>
+    int operator()(I i, const Case& case_, const Default& default_) {
+        return(boost::binary_search_switch::switch_<int>(i, case_, default_));
+    }
+};
+
+struct test_map {
+    template<class I, class Case, class Default>
+    int operator()(I i, const Case& case_, const Default& default_) {
+        return(boost::map_switch::switch_<int>(i, case_, default_));
+    }
+};
+
+struct test_sorted_array {
+    template<class I, class Case, class Default>
+    int operator()(I i, const Case& case_, const Default& default_) {
+        return(boost::sorted_array_switch::switch_<int>(i, case_, default_));
+    }
+};
+
+int main() {
+    do_test("switch", test_switch());
+    do_test("if/else", test_if_else());
+    do_test("binary_search", test_binary_search());
+    do_test("std::map", test_map());
+    do_test("sorted_array", test_sorted_array());
+}