26 #ifndef TILEDARRAY_TILE_OP_BINARY_WRAPPER_H__INCLUDED
27 #define TILEDARRAY_TILE_OP_BINARY_WRAPPER_H__INCLUDED
93 template <
typename Op>
107 template <
typename T>
110 template <
typename T>
113 template <
typename T>
115 is_lazy_tile_v<T> && !is_array_tile_v<T>;
117 template <
typename T>
132 template <
typename Perm,
typename = std::enable_if_t<
133 TiledArray::detail::is_permutation_v<Perm>>>
146 template <
typename L,
typename R,
148 !(is_lazy_tile_v<L> || is_lazy_tile_v<R>)&&!std::is_same<
150 !std::is_same<std::decay_t<R>,
ZeroTensor>::value>* =
nullptr>
151 auto operator()(L&& left, R&& right)
const {
153 std::is_same<std::decay_t<L>,
left_type>::value,
154 "BinaryWrapper::operator()(L&&,R&&): invalid argument type L");
156 std::is_same<std::decay_t<R>,
right_type>::value,
157 "BinaryWrapper::operator()(L&&,R&&): invalid argument type R");
158 if (perm_)
return op_(std::forward<L>(left), std::forward<R>(right), perm_);
160 return op_(std::forward<L>(left), std::forward<R>(right));
171 template <
typename R, std::enable_if_t<!is_lazy_tile_v<R>>* =
nullptr>
174 std::is_same<std::decay_t<R>,
right_type>::value,
175 "BinaryWrapper::operator()(zero,R&&): invalid argument type R");
176 if (perm_)
return op_(left, std::forward<R>(right), perm_);
178 return op_(left, std::forward<R>(right));
189 template <
typename L, std::enable_if_t<!is_lazy_tile_v<L>>* =
nullptr>
192 std::is_same<std::decay_t<L>,
left_type>::value,
193 "BinaryWrapper::operator()(L&&,zero): invalid argument type L");
194 if (perm_)
return op_(std::forward<L>(left), right, perm_);
196 return op_(std::forward<L>(left), right);
214 typename L,
typename R,
215 std::enable_if_t<is_lazy_tile_v<L> && is_lazy_tile_v<R> &&
217 auto operator()(L&& left, R&& right)
const {
218 auto eval_left =
invoke_cast(std::forward<L>(left));
219 auto eval_right =
invoke_cast(std::forward<R>(right));
220 auto continuation = [
this](
221 madness::future_to_ref_t<decltype(eval_left)> l,
222 madness::future_to_ref_t<decltype(eval_right)> r) {
225 return meta::invoke(continuation, eval_left, eval_right);
240 typename L,
typename R,
241 std::enable_if_t<is_lazy_tile_v<L> &&
245 auto eval_left =
invoke_cast(std::forward<L>(left));
246 auto continuation = [
this](madness::future_to_ref_t<decltype(eval_left)> l,
250 return meta::invoke(continuation, eval_left, std::forward<R>(right));
265 typename L,
typename R,
266 std::enable_if_t<(!is_lazy_tile_v<L>)&&is_lazy_tile_v<R> &&
269 auto eval_right =
invoke_cast(std::forward<R>(right));
271 [
this](L&& l, madness::future_to_ref_t<decltype(eval_right)> r) {
274 return meta::invoke(continuation, std::forward<L>(left), eval_right);
288 typename L,
typename R,
289 std::enable_if_t<is_array_tile_v<L> && is_array_tile_v<R> &&
291 auto operator()(L&& left, R&& right)
const {
292 auto eval_left =
invoke_cast(std::forward<L>(left));
293 auto eval_right =
invoke_cast(std::forward<R>(right));
295 if (perm_)
return meta::invoke(op_, eval_left, eval_right, perm_);
298 return op_.consume_left(_left, _right);
301 return op_.consume_right(_left, _right);
313 typename L,
typename R,
314 std::enable_if_t<is_array_tile_v<L> &&
318 auto eval_left =
invoke_cast(std::forward<L>(left));
320 if (perm_)
return op_(eval_left, std::forward<R>(right), perm_);
324 return op_.consume_left(eval_left, std::forward<R>(right));
326 return op_(eval_left, std::forward<R>(right));
330 typename L,
typename R,
331 std::enable_if_t<is_array_tile_v<L> && is_nonarray_lazy_tile_v<R> &&
333 auto operator()(L&& left, R&& right)
const {
334 auto eval_left =
invoke_cast(std::forward<L>(left));
335 auto eval_right =
invoke_cast(std::forward<R>(right));
337 if (perm_)
return op_(eval_left, eval_right, perm_);
341 return op_.consume_left(eval_left, eval_right);
343 return op_(eval_left, eval_right);
347 typename L,
typename R,
348 std::enable_if_t<(!is_lazy_tile_v<L>)&&is_array_tile_v<R> &&
351 auto eval_right =
invoke_cast(std::forward<R>(right));
353 if (perm_)
return op_(std::forward<L>(left), eval_right, perm_);
357 return op_.consume_right(std::forward<L>(left), eval_right);
359 return op_(std::forward<L>(left), eval_right);
363 typename L,
typename R,
364 std::enable_if_t<is_nonarray_lazy_tile_v<L> && is_array_tile_v<R> &&
366 auto operator()(L&& left, R&& right)
const {
367 auto eval_left =
invoke_cast(std::forward<L>(left));
368 auto eval_right =
invoke_cast(std::forward<R>(right));
370 if (perm_)
return op_(eval_left, eval_right, perm_);
374 return op_.consume_right(eval_left, eval_right);
376 return op_(eval_left, eval_right);
384 #endif // TILEDARRAY_TILE_OP_BINARY_WRAPPER_H__INCLUDED