In Intel Cilk Plus extension there's this keyword cilk_for (or _Cilk_for actually). It's like the keyword for, but more restrictive and its iterations run in parallel. I wrote a convenience macro in the spirit of BOOST_FOREACH, which uses cilk_for internally. Can you see any problems with the following implementation?
#pragma once
#include <iterator>
#include <boost/preprocessor/cat.hpp>
#include <cilk/cilk.h>
#define cilk_foreach(_decl_var_, _expr_range_) \
CILK_FOREACH_I(_decl_var_, _expr_range_, __COUNTER__)
#define CILK_FOREACH_I(_decl_var_, _expr_range_, _id_) \
CILK_FOREACH_II(_decl_var_, \
_expr_range_, \
BOOST_PP_CAT(_range_3s236dw221GyVcf46_, _id_), \
BOOST_PP_CAT(_end_5Y60u42bIp7DZd88f2c_, _id_), \
BOOST_PP_CAT(_itr_6V970q8n4Etv0i8bf50_, _id_), \
BOOST_PP_CAT(_continue_4rtWH641r5cXqU_, _id_))
#define CILK_FOREACH_II(_decl_var_, _expr_range_, _range_, _end_, _itr_, _cont_) \
auto&& _range_ = _expr_range_; \
auto _end_ = std::end(_range_); \
\
cilk_for (auto _itr_ = std::begin(_range_); _itr_ != _end_; ++_itr_) \
if (auto _cont_ = true) \
for (_decl_var_ = *_itr_; _cont_; _cont_ = false)
You would use it like so:
std::vector<int> values (10);
cilk_foreach (auto& value , values)
{
value += 123;
}
EDIT
template <typename T>
struct Wrap
{
T& data;
explicit Wrap(T&& data)
: data (data)
{}
operator bool() const
{
return true;
}
};
template <typename T>
Wrap<T> wrap(T&& data)
{
return Wrap<T>(std::forward<T>(data));
}
#define cilk_foreach(_decl_var_, _expr_range_) \
CILK_FOREACH_I(_decl_var_, _expr_range_, __COUNTER__)
#define CILK_FOREACH_I(_decl_var_, _expr_range_, _id_) \
\
CILK_FOREACH_II(_decl_var_, \
_expr_range_, \
BOOST_PP_CAT(_range_3s236dw221GyVcf46_, _id_), \
BOOST_PP_CAT(_itr_6V970q8n4Etv0i8bf50_, _id_), \
BOOST_PP_CAT(_continue_4rtWH641r5cXqU_, _id_))
#define CILK_FOREACH_II(_decl_var_, _expr_range_, _range_, _itr_, _cont_) \
\
if (auto _range_ = wrap(_expr_range_)) \
cilk_for (auto _itr_ = std::begin(_range_.data); \
_itr_ != std::end (_range_.data); \
++_itr_) \
if (auto _cont_ = true) \
for (_decl_var_ = *_itr_; _cont_; _cont_ = false)
You should probably read this: C++ Boost: Any gotchas with BOOST_FOREACH?
One obvious problem is that your marco doesn't expand into something that has the lexical type it looks like it has. As an example, consider
if(condition)
cilk_foreach (auto& value , values) {
//stuff
}
or even worse
if(condition)
cilk_foreach (auto& value , values)
// one-line stuff
else
// other stuff