TiledArray  0.7.0
unary_wrapper.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2013 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * binary_interface.h
22  * Oct 6, 2013
23  *
24  */
25 
26 #ifndef TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
27 #define TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
28 
30 #include <TiledArray/permutation.h>
31 #include <TiledArray/zero_tensor.h>
32 
33 namespace TiledArray {
34  namespace detail {
35 
37 
81  template <typename Op>
82  class UnaryWrapper {
83  public:
85  typedef typename Op::argument_type argument_type;
86  typedef typename Op::result_type result_type;
87 
88 
90  static constexpr bool is_consumable = Op::is_consumable;
91 
92  template <typename T>
93  static constexpr auto is_lazy_tile_v = is_lazy_tile<std::decay_t<T>>::value;
94 
95  template <typename T>
96  static constexpr auto is_array_tile_v = is_array_tile<std::decay_t<T>>::value;
97 
98  template <typename T>
99  static constexpr auto is_nonarray_lazy_tile_v = is_lazy_tile_v<T> && !is_array_tile_v<T>;
100 
101  template <typename T>
102  using eval_t = typename eval_trait<std::decay_t<T> >::type;
103 
104  private:
105 
106  Op op_;
107  Permutation perm_;
108 
109  public:
110 
111  // Compiler generated functions
112  UnaryWrapper(const UnaryWrapper_&) = default;
113  UnaryWrapper(UnaryWrapper_&&) = default;
114  ~UnaryWrapper() = default;
115  UnaryWrapper_& operator=(const UnaryWrapper_&) = default;
116  UnaryWrapper_& operator=(UnaryWrapper_&&) = default;
117 
118  UnaryWrapper(const Op& op, const Permutation& perm) : op_(op), perm_(perm) { }
119 
120  UnaryWrapper(const Op& op) : op_(op), perm_() { }
121 
122 
124 
126  const Permutation& permutation() const { return perm_; }
127 
128 
130 
134  auto operator()(argument_type& arg) const {
135  return (perm_ ? op_(arg, perm_) : op_(arg) );
136  }
137 
139 
143  auto operator()(const argument_type& arg) const {
144  return (perm_ ? op_(arg, perm_) : op_(arg) );
145  }
146 
148 
155  template <typename A,
156  std::enable_if_t<is_nonarray_lazy_tile_v<A>>* = nullptr>
157  auto operator()(A&& arg) const {
159  return (perm_ ? invoke(op_, invoke_cast(std::forward<A>(arg)), perm_)
160  : invoke(op_, invoke_cast(std::forward<A>(arg))));
161  }
162 
164 
171  template <typename A, std::enable_if_t<is_array_tile_v<A>>* = nullptr>
172  auto operator()(A&& arg) const {
173  auto cast_arg = invoke_cast(std::forward<A>(arg));
174  // TODO replace with generic lambda, replace cast_arg with std::move(cast_arg)
175 // NB using this generic lambda breaks TaskFn ...
176 // need to make TaskFn variadic and accepting callables, but this is a lot of MP
177 //
178 // auto op_consume = [this](auto&& arg) {
179 // return op_.consume(std::forward<decltype(arg)>(arg));
180 // };
181  auto op_consume = [this](eval_t<A>& arg) {
182  return op_.consume(arg);
183  };
185  return (perm_ ? invoke(op_, std::move(cast_arg), perm_)
186  : (arg.is_consumable()
187  ? invoke(op_consume, cast_arg)
188  : invoke(op_, std::move(cast_arg))));
189  }
190 
192  template <typename A, std::enable_if_t<is_lazy_tile_v<A>>* = nullptr>
193  auto consume(A&& arg) const {
194  auto cast_arg = invoke_cast(std::forward<A>(arg));
195  // TODO replace with generic lambda, replace cast_arg with std::move(cast_arg)
196 // NB using this generic lambda breaks TaskFn ...
197 // need to make TaskFn variadic and accepting callables, but this is a lot of MP
198 //
199 // auto op_consume = [this](auto&& arg) {
200 // return op_.consume(std::forward<decltype(arg)>(arg));
201 // };
202  auto op_consume = [this](eval_t<A>& arg) {
203  return op_.consume(arg);
204  };
206  return (perm_ ?
207  invoke(op_, std::move(cast_arg), perm_) :
208  invoke(op_consume, cast_arg));
209  }
210 
211  template <typename A, std::enable_if_t<!is_lazy_tile_v<A>>* = nullptr>
212  result_type consume(A&& arg) const {
213  static_assert(std::is_same<std::decay_t<A>, argument_type>::value,
214  "UnaryWrapper::consume(A&&): invalid argument type A");
215  return (perm_ ? op_(std::forward<A>(arg), perm_)
216  : op_.consume(std::forward<A>(arg)));
217  }
218 
219  }; // class UnaryWrapper
220 
221  } // namespace detail
222 } // namespace TiledArray
223 
224 #endif // TILEDARRAY_TILE_OP_UNARY_WRAPPER_H__INCLUDED
auto invoke_cast(Arg &&arg)
Definition: cast.h:178
auto consume(A &&arg) const
Consume a lazy tile.
result_type consume(A &&arg) const
UnaryWrapper< Op > UnaryWrapper_
Definition: unary_wrapper.h:84
Determine the object type used in the evaluation of tensor expressions.
Definition: type_traits.h:296
static constexpr auto is_array_tile_v
Definition: unary_wrapper.h:96
Unary tile operation wrapper.
Definition: unary_wrapper.h:82
auto operator()(const argument_type &arg) const
Apply operator to arg and possibly permute the result.
Op::result_type result_type
The result tile type.
Definition: unary_wrapper.h:86
static constexpr auto is_nonarray_lazy_tile_v
Definition: unary_wrapper.h:99
auto operator()(argument_type &arg) const
Apply operator to arg and possibly permute the result.
typename eval_trait< std::decay_t< T > >::type eval_t
Op::argument_type argument_type
Argument type.
Definition: unary_wrapper.h:85
Detect tiles used by ArrayEvalImpl.
Definition: type_traits.h:451
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
const Permutation & permutation() const
Permutation accessor.
UnaryWrapper(const Op &op, const Permutation &perm)
static constexpr bool is_consumable
Boolean value that indicates the argument can always be consumed.
Definition: unary_wrapper.h:90
auto invoke(Function &&fn, Args &&... args) -> typename std::enable_if< !or_reduce< false, madness::is_future< std::decay_t< Args >>::value... >::value, decltype(fn(args...))>::type
Definition: meta.h:52
UnaryWrapper(const UnaryWrapper_ &)=default
Detect lazy evaluation tiles.
Definition: type_traits.h:388
auto operator()(A &&arg) const
Evaluate a lazy tile.
static constexpr auto is_lazy_tile_v
Definition: unary_wrapper.h:93
UnaryWrapper_ & operator=(const UnaryWrapper_ &)=default