|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r51108 - sandbox/interthreads/boost/interthreads/algorithm
From: vicente.botet_at_[hidden]
Date: 2009-02-08 16:08:01
Author: viboes
Date: 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
New Revision: 51108
URL: http://svn.boost.org/trac/boost/changeset/51108
Log:
interthreads version 0.4
* New free functions for all the AsynchronousCompletionToken operations, providing a higher degree of freedom.
* Missing have_all_values(), have_all_exception() and are_all_ready() functions on AsynchronousCompletionToken fusion tuples.
* get_all: getting all the values from a tuple of AsynchronousCompletionToken works now.
* fork_after overloaded for a single dependency
* wait_all overloaded for a single ACT.
* wait_for_all evaluate one of its elements on the current thread
* No need to use wait_and_get() on thread_specific_shared_ptr<> to synchronize with the decoration if the thread is created using a AsynchronousExecutor decorator. In this case the synchro is done before returning the AsynchronousCompletionToken. See the tutorial and the mono_thread_id example.
Text files modified:
sandbox/interthreads/boost/interthreads/algorithm/detach_all.hpp | 9 +-
sandbox/interthreads/boost/interthreads/algorithm/get_all.hpp | 138 ++++++++++++++++++++++++++++++++-------
sandbox/interthreads/boost/interthreads/algorithm/get_all_until.hpp | 21 +++--
sandbox/interthreads/boost/interthreads/algorithm/interrupt_all.hpp | 12 ++-
sandbox/interthreads/boost/interthreads/algorithm/interruption_requested_on_all.hpp | 14 ++--
sandbox/interthreads/boost/interthreads/algorithm/join_all.hpp | 8 +
sandbox/interthreads/boost/interthreads/algorithm/join_all_until.hpp | 125 ++++++++++++++++++++++++++++++++---
sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp | 23 +++++-
sandbox/interthreads/boost/interthreads/algorithm/wait_all_until.hpp | 139 ++++++++++++++++++++++++++++++++++-----
9 files changed, 400 insertions(+), 89 deletions(-)
Modified: sandbox/interthreads/boost/interthreads/algorithm/detach_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/detach_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/detach_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -12,6 +12,7 @@
#define BOOST_INTERTHREADS_DETACH_ALL__HPP
#include <boost/fusion/include/for_each.hpp>
+#include <boost/interthreads/algorithm/detach.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -34,14 +35,14 @@
typedef typename fusion::result_of::for_each<Sequence, fct::detach>::type type;
};
}
-
+
template <typename Sequence>
void detach_all(Sequence& t) {
fusion::for_each(t, fct::detach());
}
-
-}
+
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/get_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/get_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/get_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -14,8 +14,12 @@
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/zip_view.hpp>
#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/as_vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/interthreads/algorithm/get.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -23,65 +27,147 @@
namespace interthreads {
namespace fct {
struct get {
- template<typename Sig>
+ template <typename Sig>
struct result;
- template<typename T>
+ template <typename T>
struct result<get(T)>
{
- typedef typename boost::remove_reference<T>::type ACT;
- typedef typename ACT::result_type type;
+ typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type ACT;
+ typedef typename act_traits<ACT>::move_dest_type type;
};
-
- template<typename ACT>
+
+ template <typename ACT>
typename ACT::result_type operator()(ACT& act) const {
- return act.get();
+ return typename ACT::result_type();
}
};
- struct intrusive_get {
+
+ struct set {
template<typename Sig>
struct result;
template<typename T>
- struct result<intrusive_get(T)>
+ struct result<set(T)>
{
typedef void type;
};
-
+
template<typename ACT_VAL>
void operator()(ACT_VAL act_val) const {
- fusion::at_c<1>(act_val)=fusion::at_c<0>(act_val).get();
+ fusion::at_c<1>(act_val)=interthreads::get(fusion::at_c<0>(act_val));
}
};
}
-
namespace result_of {
template <typename Sequence>
- struct get_all {
- typedef typename fusion::result_of::transform<Sequence const, fct::get>::type type;
+ struct set_all {
+ typedef void type;
};
- }
- template <typename Sequence>
- typename result_of::get_all<Sequence>::type
- get_all(Sequence& t) {
- return fusion::transform(t, fct::get());
- }
- namespace result_of {
template <typename Sequence>
- struct set_all {
- typedef void type;
+ struct get_all {
+ typedef typename fusion::result_of::as_vector<
+ typename fusion::result_of::transform<Sequence const, fct::get>::type
+ >::type type;
};
}
+
template <typename SequenceHandles, typename SequenceValues>
void set_all(SequenceHandles& handles, SequenceValues& values) {
typedef fusion::vector<SequenceHandles&, SequenceValues&> sequences;
sequences seqs(handles, values);
fusion::zip_view<sequences> zip(seqs);
- fusion::for_each(zip, fct::intrusive_get());
+ fusion::for_each(zip, fct::set());
+ }
+
+#if 0
+namespace detail {
+ template<int N>
+ struct get_all_unrolled
+ {
+ template<typename I0>
+ static void call(I0& i0)
+ {
+ fct::get()(*i0);
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ fct::get()(*i1);
+ typedef typename fusion::result_of::next<I1>::type I2;
+ I2 i2(fusion::next(i1));
+ fct::get()(*i2);
+ typedef typename fusion::result_of::next<I2>::type I3;
+ I3 i3(fusion::next(i2));
+ fct::get()(*i3);
+ return get_all_unrolled<N-4>::call(fusion::next(i3), abs_time);
+ }
+ };
+
+ template<>
+ struct get_all_unrolled<3>
+ {
+ template<typename I0>
+ static bool call(I0& i0)
+ {
+ }
+ };
+
+ template<>
+ struct get_all_unrolled<2>
+ {
+ template<typename I0>
+ static bool call(I0& i0)
+ {
+ }
+ };
+
+ template<>
+ struct get_all_unrolled<1>
+ {
+ template<typename I0>
+ static bool call(I0& i0)
+ {
+ return fct::get()(*i0);
+ }
+ };
+
+ template<>
+ struct get_all_unrolled<0>
+ {
+ template<typename It>
+ static bool call(It const&, const system_time&)
+ {
+ return true;
+ }
+ };
+
+ template <typename Sequence>
+ inline typename result_of::template get_all<Sequence>::type
+ get_all(Sequence& seq, const system_time& abs_time, fusion::random_access_traversal_tag)
+ {
+ typedef typename fusion::result_of::begin<Sequence>::type begin;
+ typedef typename fusion::result_of::end<Sequence>::type end;
+ return get_all_unrolled<fusion::result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), abs_time);
}
-}
+
+
+}
+#endif
+
+ template <typename Sequence>
+ typename result_of::template get_all<Sequence>::type
+ get_all(Sequence& seq) {
+#if 0
+ return detail::get_all(seq, abs_time, typename fusion::traits::category_of<Sequence>::type());
+#else
+ typename result_of::template get_all<Sequence>::type res=fusion::as_vector(fusion::transform(seq, fct::get()));
+ set_all(seq, res);
+ return res;
+#endif
+ }
+
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/get_all_until.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/get_all_until.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/get_all_until.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -23,7 +23,8 @@
#else
#include <boost/thread/thread_time.hpp>
#endif
-#include <boost/interthreads/algorithm/get_all.hpp>
+#include <boost/interthreads/algorithm/get_until.hpp>
+//#include <boost/interthreads/algorithm/get_all.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -35,7 +36,7 @@
get_until(const system_time& abs_time) : abs_time_(abs_time) {}
template<typename ACT>
typename std::pair<bool,typename ACT::result_type> operator()(ACT& act) const {
- return act.get_until(abs_time_);
+ return interthreads::get_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -48,7 +49,7 @@
get_for(const Duration& abs_time) : abs_time_(get_system_time()+abs_time) {}
template<typename ACT>
typename std::pair<bool,typename ACT::result_type> operator()(ACT& act) const {
- return act.get_until(abs_time_);
+ return interthreads::get_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -68,12 +69,12 @@
typedef std::pair<bool, typename result_of::get_all<Sequence>::type > type;
};
}
-
+
template <typename Sequence>
- typename result_of::get_all_until<Sequence>
+ typename result_of::template get_all_until<Sequence>::type
get_all_until(Sequence& t, const system_time& abs_time) {
std::pair<bool,typename fusion::result_of::at_c<Sequence, 0>::type::result_type > r = fct::get_until(abs_time)(fusion::at_c<0>(t));
- if (r.first) return std::make_pair(true, result_of::get_all<Sequence>::type());
+ if (r.first) return std::make_pair(true, result_of::get_all<Sequence>::type());
else {
if (fusion::size(t)==1) {
return std::make_pair(false, result_of::get_all<Sequence>::type(r.first));
@@ -85,13 +86,13 @@
}
template <typename Sequence, typename Duration>
- typename result_of::get_all_for<Sequence>
- get_all_for(Sequence& t, const Duration& rel_time) {
+ typename result_of::template get_all_for<Sequence>::type
+ get_all_for(Sequence& t, Duration rel_time) {
return get_all_until(t, get_system_time()+rel_time);
}
-}
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/interrupt_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/interrupt_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/interrupt_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -12,21 +12,23 @@
#define BOOST_INTERTHREADS_INTERRUPT_ALL__HPP
#include <boost/fusion/include/for_each.hpp>
+#include <boost/interthreads/algorithm/interrupt.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost {
namespace interthreads {
-
+
namespace fct {
struct interrupt {
template<typename ACT>
void operator()(ACT& act) const {
- act.interrupt();
+ //std::cout << "interrupt_all::interrupt" << std::endl;
+ interthreads::interrupt(act);
}
};
}
-
+
namespace result_of {
template <typename Sequence>
struct interrupt_all {
@@ -39,7 +41,7 @@
fusion::for_each(t, fct::interrupt());
}
-}
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/interruption_requested_on_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/interruption_requested_on_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/interruption_requested_on_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -13,18 +13,19 @@
#include <boost/fusion/include/all.hpp>
+#include <boost/interthreads/algorithm/interruption_requested.hpp>
+
#include <boost/config/abi_prefix.hpp>
-namespace boost {
-namespace interthreads {
-
+namespace boost { namespace interthreads {
+
namespace fct {
struct interruption_requested {
typedef bool result_type;
template<typename ACT>
bool operator()(ACT& act) const {
- return act.interruption_requested();
+ return interthreads::interruption_requested(act);
}
};
}
@@ -42,8 +43,7 @@
}
-}
-} // namespace boost
+}} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/join_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/join_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/join_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -19,6 +19,8 @@
#include <boost/thread/thread_time.hpp>
#endif
+#include <boost/interthreads/algorithm/join.hpp>
+
#include <boost/config/abi_prefix.hpp>
namespace boost {
@@ -29,7 +31,7 @@
typedef void result_type;
template<typename ACT>
void operator()(ACT& act) const {
- act.join();
+ interthreads::join(act);
}
};
}
@@ -47,7 +49,7 @@
return fusion::for_each(t, fct::join());
}
-}
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/join_all_until.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/join_all_until.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/join_all_until.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -18,6 +18,7 @@
#else
#include <boost/thread/thread_time.hpp>
#endif
+#include <boost/interthreads/algorithm/join_until.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -29,7 +30,7 @@
join_until(const system_time& abs_time) : abs_time_(abs_time) {}
template<typename ACT>
bool operator()(ACT& act) const {
- return act.join_until(abs_time_);
+ return interthreads::join_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -42,7 +43,7 @@
join_for(const Duration& rel_time) : abs_time_(get_system_time()+rel_time) {}
template<typename ACT>
bool operator()(ACT& act) const {
- return act.join_until(abs_time_);
+ return join_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -62,28 +63,128 @@
};
}
-
+namespace detail {
+ template<int N>
+ struct join_all_until_unrolled
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::join_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ if(fct::join_until(abs_time)(*i1)) return true;
+ else {
+ typedef typename fusion::result_of::next<I1>::type I2;
+ I2 i2(fusion::next(i1));
+ if(fct::join_until(abs_time)(*i2)) return true;
+ else {
+ typedef typename fusion::result_of::next<I2>::type I3;
+ I3 i3(fusion::next(i2));
+ if(fct::join_until(abs_time)(*i3)) return true;
+ else {
+ return join_all_until_unrolled<N-4>::call(fusion::next(i3), abs_time);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ template<>
+ struct join_all_until_unrolled<3>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::join_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ if(fct::join_until(abs_time)(*i1)) return true;
+ else {
+ typedef typename fusion::result_of::next<I1>::type I2;
+ I2 i2(fusion::next(i1));
+ return fct::join_until(abs_time)(*i2);
+ }
+ }
+ }
+ };
+
+ template<>
+ struct join_all_until_unrolled<2>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::join_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ return fct::join_until(abs_time)(*i1);
+ }
+ }
+ };
+
+ template<>
+ struct join_all_until_unrolled<1>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ return fct::join_until(abs_time)(*i0);
+ }
+ };
+
+ template<>
+ struct join_all_until_unrolled<0>
+ {
+ template<typename It>
+ static bool call(It const&, const system_time&)
+ {
+ return true;
+ }
+ };
+
+ template <typename Sequence>
+ inline typename result_of::template join_all_until<Sequence>::type
+ join_all_until(Sequence& seq, const system_time& abs_time, fusion::random_access_traversal_tag)
+ {
+ typedef typename fusion::result_of::begin<Sequence>::type begin;
+ typedef typename fusion::result_of::end<Sequence>::type end;
+ return join_all_until_unrolled<fusion::result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), abs_time);
+ }
+
+
+}
+
+
template <typename Sequence>
- typename result_of::join_all_until<Sequence>
- join_all_until(Sequence& t, const system_time& abs_time) {
+ typename result_of::template join_all_until<Sequence>::type
+ join_all_until(Sequence& seq, const system_time& abs_time) {
+#if 1
+ return detail::join_all_until(seq, abs_time, typename fusion::traits::category_of<Sequence>::type());
+#else
bool r = fct::join_until(abs_time)(fusion::at_c<0>(t));
- if (r) return true;
+ if (r) return true;
else {
if (fusion::size(t)==1) {
return false;
} else {
- return get_all_until(fusion::pop_front(t));
+ return join_all_until(fusion::pop_front(t), abs_time);
}
}
+#endif
}
template <typename Sequence, typename Duration>
- typename result_of::join_all_for<Sequence>
- join_all_for(Sequence& t, const Duration& rel_time) {
- return join_all_until(t, get_system_time()+rel_time);
+ typename result_of::template join_all_for<Sequence>::type
+ join_all_for(Sequence& seq, Duration rel_time) {
+ return join_all_until(seq, get_system_time()+rel_time);
}
-}
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/wait_all.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -19,6 +19,11 @@
#include <boost/thread/thread_time.hpp>
#endif
+#include <boost/interthreads/algorithm/wait.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/utility/enable_if.hpp>
+//#include <boost/utility/disable_if.hpp>
+
#include <boost/config/abi_prefix.hpp>
namespace boost {
@@ -29,7 +34,7 @@
typedef void result_type;
template<typename ACT>
void operator()(ACT& act) const {
- act.wait();
+ interthreads::wait(act);
}
};
}
@@ -41,13 +46,23 @@
};
}
+
template <typename Sequence>
- typename result_of::wait_all<Sequence>::type
+ typename boost::enable_if<fusion::traits::is_sequence<Sequence>,
+ typename result_of::template wait_all<Sequence>::type
+ >::type
wait_all(Sequence& t) {
fusion::for_each(t, fct::wait());
}
-}
+ template <typename ACT>
+ typename boost::disable_if<fusion::traits::is_sequence<ACT>,
+ typename result_of::template wait<ACT>::type
+ >::type
+ wait_all(ACT& t) {
+ interthreads::wait(t);
+ }
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Modified: sandbox/interthreads/boost/interthreads/algorithm/wait_all_until.hpp
==============================================================================
--- sandbox/interthreads/boost/interthreads/algorithm/wait_all_until.hpp (original)
+++ sandbox/interthreads/boost/interthreads/algorithm/wait_all_until.hpp 2009-02-08 16:08:00 EST (Sun, 08 Feb 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Vicente J. Botet Escriba 2008-20009. Distributed under the Boost
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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)
//
@@ -13,23 +13,37 @@
#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/distance.hpp>
+//#include <boost/fusion/inlude/next.hpp>
+#include <boost/mpl/bool.hpp>
+
+
#ifdef BOOST_HAS_CHRONO_LIB
#include <boost/chono/chono.hpp>
#else
#include <boost/thread/thread_time.hpp>
#endif
+#include <boost/interthreads/algorithm/wait_until.hpp>
+
#include <boost/config/abi_prefix.hpp>
namespace boost {
namespace interthreads {
+
+
namespace fct {
struct wait_until {
wait_until(const system_time& abs_time) : abs_time_(abs_time) {}
template<typename ACT>
bool operator()(ACT& act) const {
- return act.wait_until(abs_time_);
+ return interthreads::wait_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -42,7 +56,7 @@
wait_for(const Duration& rel_time) : abs_time_(get_system_time()+rel_time) {}
template<typename ACT>
bool operator()(ACT& act) const {
- return act.wait_until(abs_time_);
+ return wait_until(act, abs_time_);
}
private:
const system_time& abs_time_;
@@ -62,29 +76,118 @@
typedef bool type;
};
}
-
- template <typename Sequence>
- typename result_of::wait_all_until<Sequence const>
- wait_all_until(Sequence const& t, const system_time& abs_time) {
- bool r = fct::wait_until(abs_time)(fusion::at_c<0>(t));
- if (r) return true;
- else {
- if (fusion::size(t)==1) {
- return false;
- } else {
- return get_all_until(fusion::pop_front(t));
+
+
+namespace detail {
+ template<int N>
+ struct wait_all_until_unrolled
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::wait_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ if(fct::wait_until(abs_time)(*i1)) return true;
+ else {
+ typedef typename fusion::result_of::next<I1>::type I2;
+ I2 i2(fusion::next(i1));
+ if(fct::wait_until(abs_time)(*i2)) return true;
+ else {
+ typedef typename fusion::result_of::next<I2>::type I3;
+ I3 i3(fusion::next(i2));
+ if(fct::wait_until(abs_time)(*i3)) return true;
+ else {
+ return wait_all_until_unrolled<N-4>::call(fusion::next(i3), abs_time);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ template<>
+ struct wait_all_until_unrolled<3>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::wait_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ if(fct::wait_until(abs_time)(*i1)) return true;
+ else {
+ typedef typename fusion::result_of::next<I1>::type I2;
+ I2 i2(fusion::next(i1));
+ return fct::wait_until(abs_time)(*i2);
+ }
+ }
+ }
+ };
+
+ template<>
+ struct wait_all_until_unrolled<2>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ if (fct::wait_until(abs_time)(*i0)) return true;
+ else {
+ typedef typename fusion::result_of::next<I0>::type I1;
+ I1 i1(fusion::next(i0));
+ return fct::wait_until(abs_time)(*i1);
}
}
+ };
+
+ template<>
+ struct wait_all_until_unrolled<1>
+ {
+ template<typename I0>
+ static bool call(I0 const& i0, const system_time& abs_time)
+ {
+ return fct::wait_until(abs_time)(*i0);
+ }
+ };
+
+ template<>
+ struct wait_all_until_unrolled<0>
+ {
+ template<typename It>
+ static bool call(It const&, const system_time&)
+ {
+ return true;
+ }
+ };
+
+ template <typename Sequence>
+ inline typename result_of::template wait_all_until<Sequence>::type
+ wait_all_until(Sequence& seq, const system_time& abs_time, fusion::random_access_traversal_tag)
+ {
+ typedef typename fusion::result_of::begin<Sequence>::type begin;
+ typedef typename fusion::result_of::end<Sequence>::type end;
+ return wait_all_until_unrolled<fusion::result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), abs_time);
+ }
+
+
+}
+
+ template <typename Sequence>
+ typename result_of::template wait_all_until<Sequence>::type
+ wait_all_until(Sequence& seq, const system_time& abs_time) {
+ return detail::wait_all_until(seq, abs_time, typename fusion::traits::category_of<Sequence>::type());
}
template <typename Sequence, typename Duration>
- typename result_of::wait_all_for<Sequence>
- wait_all_for(Sequence& t, const Duration& rel_time) {
+ typename result_of::template wait_all_for<Sequence>::type
+ wait_all_for(Sequence& t, Duration rel_time) {
return wait_all_until(t, get_system_time()+rel_time);
}
-
-}
+
+}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk