add.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2016 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  * add.h
22  * Jan 11, 2016
23  *
24  */
25 
26 #ifndef TILEDARRAY_TILE_INTERFACE_ADD_H__INCLUDED
27 #define TILEDARRAY_TILE_INTERFACE_ADD_H__INCLUDED
28 
29 #include "../tile_interface/cast.h"
30 #include "../tile_interface/permute.h"
31 #include "../type_traits.h"
32 
33 namespace TiledArray {
34 
36 
42 template <typename Left, typename Right>
43 inline auto add(const Left& left, const Right& right)
44  -> decltype(left.add(right)) {
45  return left.add(right);
46 }
47 
49 
57 template <
58  typename Left, typename Right, typename Scalar,
59  typename std::enable_if<detail::is_numeric_v<Scalar>>::type* = nullptr>
60 inline auto add(const Left& left, const Right& right, const Scalar factor) {
61  return left.add(right, factor);
62 }
63 
65 
72 template <
73  typename Left, typename Right, typename Perm,
74  typename = std::enable_if_t<TiledArray::detail::is_permutation_v<Perm> &&
75  detail::has_member_function_add_anyreturn_v<
76  const Left, const Right&, const Perm&>>>
77 inline auto add(const Left& left, const Right& right, const Perm& perm) {
78  return left.add(right, perm);
79 }
80 
82 
91 template <
92  typename Left, typename Right, typename Scalar, typename Perm,
93  typename std::enable_if<detail::is_numeric_v<Scalar> &&
94  detail::is_permutation_v<Perm>>::type* = nullptr>
95 inline auto add(const Left& left, const Right& right, const Scalar factor,
96  const Perm& perm) {
97  return left.add(right, factor, perm);
98 }
99 
101 
107 template <typename Result, typename Arg>
108 inline Result& add_to(Result& result, const Arg& arg) {
109  return result.add_to(arg);
110 }
111 
113 
121 template <
122  typename Result, typename Arg, typename Scalar,
123  typename std::enable_if<detail::is_numeric_v<Scalar>>::type* = nullptr>
124 inline Result& add_to(Result& result, const Arg& arg, const Scalar factor) {
125  return result.add_to(arg, factor);
126 }
127 
128 namespace tile_interface {
129 
130 using TiledArray::add;
131 using TiledArray::add_to;
132 
133 template <typename... T>
134 using result_of_add_t = decltype(add(std::declval<T>()...));
135 
136 template <typename... T>
137 using result_of_add_to_t = decltype(add_to(std::declval<T>()...));
138 
139 // template <typename Left, typename Right, typename Enabler = void>
140 // struct add_trait {
141 // typedef Left type;
142 // };
143 //
144 // template <typename Left, typename Right>
145 // struct add_trait<Left, Right,
146 // typename std::enable_if<
147 // TiledArray::detail::is_type<result_of_add_t<Left, Right> >::value
148 // >::type>
149 // {
150 // typedef result_of_add_t<Left, Right> type;
151 // };
152 //
153 // template <typename Left, typename Right, typename Enabler = void>
154 // struct scal_add_trait :
155 // public scal_trait<typename add_trait<Left, Right>::type, Scalar>
156 // { };
157 //
158 // template <typename Left, typename Right, typename Scalar>
159 // struct scal_add_trait<Left, Right,
160 // typename std::enable_if<
161 // TiledArray::detail::is_type<result_of_add_t<Left, Right, Scalar>
162 // >::value
163 // >::type>
164 // {
165 // typedef result_of_add_t<Left, Right, Scalar> type;
166 // };
167 
168 template <typename Result, typename Left, typename Right,
169  typename Enabler = void>
170 class Add {
171  public:
172  typedef Result result_type;
173  typedef Left left_type;
174  typedef Right right_type;
175 
176  result_type operator()(const left_type& left, const right_type& right) const {
177  using TiledArray::add;
178  return add(left, right);
179  }
180 
181  template <typename Perm, typename = std::enable_if_t<
182  TiledArray::detail::is_permutation_v<Perm>>>
183  result_type operator()(const left_type& left, const right_type& right,
184  const Perm& perm) const {
185  using TiledArray::add;
186  return add(left, right, perm);
187  }
188 };
189 
190 template <typename Result, typename Left, typename Right>
191 class Add<Result, Left, Right,
192  typename std::enable_if<!(
193  std::is_same<Result, result_of_add_t<Left, Right>>::value &&
194  std::is_same<Result,
195  result_of_add_t<Left, Right, BipartitePermutation>>::
196  value)>::type> {
197  public:
198  typedef Result result_type;
199  typedef Left left_type;
200  typedef Right right_type;
201 
202  result_type operator()(const left_type& left, const right_type& right) const {
203  using TiledArray::add;
205  return cast(add(left, right));
206  }
207 
208  template <typename Perm, typename = std::enable_if_t<
209  TiledArray::detail::is_permutation_v<Perm>>>
210  result_type operator()(const left_type& left, const right_type& right,
211  const Perm& perm) const {
212  using TiledArray::add;
214  return cast(add(left, right, perm));
215  }
216 };
217 
218 template <typename Result, typename Left, typename Right, typename Scalar,
219  typename Enabler = void>
220 class ScalAdd {
221  public:
222  static_assert(TiledArray::detail::is_numeric_v<Scalar>,
223  "Cannot scale tiles by a non-scalar type");
224 
225  typedef Result result_type;
226  typedef Left left_type;
227  typedef Right right_type;
228  typedef Scalar scalar_type;
229 
230  result_type operator()(const left_type& left, const right_type& right,
231  const scalar_type factor) const {
232  using TiledArray::add;
233  return add(left, right, factor);
234  }
235 
236  template <typename Perm, typename = std::enable_if_t<
237  TiledArray::detail::is_permutation_v<Perm>>>
238  result_type operator()(const left_type& left, const right_type& right,
239  const scalar_type factor, const Perm& perm) const {
240  using TiledArray::add;
241  return add(left, right, factor, perm);
242  }
243 };
244 
245 template <typename Result, typename Left, typename Right, typename Scalar>
246 class ScalAdd<
247  Result, Left, Right, Scalar,
248  typename std::enable_if<!(
249  std::is_same<Result, result_of_add_t<Left, Right, Scalar>>::value &&
250  std::is_same<Result, result_of_add_t<Left, Right, Scalar,
251  BipartitePermutation>>::value)>::
252  type> {
253  public:
254  static_assert(TiledArray::detail::is_numeric_v<Scalar>,
255  "Cannot scale tiles by a non-scalar type");
256 
257  typedef Result result_type;
258  typedef Left left_type;
259  typedef Right right_type;
260  typedef Scalar scalar_type;
261 
262  result_type operator()(const left_type& left, const right_type& right,
263  const scalar_type factor) const {
264  using TiledArray::add;
266  return cast(add(left, right, factor));
267  }
268 
269  template <typename Perm, typename = std::enable_if_t<
270  TiledArray::detail::is_permutation_v<Perm>>>
271  result_type operator()(const left_type& left, const right_type& right,
272  const scalar_type factor, const Perm& perm) const {
273  using TiledArray::add;
275  return cast(add(left, right, factor, perm));
276  }
277 };
278 
279 template <typename Result, typename Left, typename Right,
280  typename Enabler = void>
281 class AddTo {
282  public:
283  typedef Result result_type;
284  typedef Left left_type;
285  typedef Right right_type;
286 
287  result_type& operator()(left_type& left, const right_type& right) const {
288  using TiledArray::add_to;
289  return add_to(left, right);
290  }
291 };
292 
293 template <typename Result, typename Left, typename Right>
294 class AddTo<Result, Left, Right,
295  typename std::enable_if<!std::is_same<
296  Result, result_of_add_to_t<Left, Right>>::value>::type> {
297  public:
298  typedef Result result_type;
299  typedef Left left_type;
300  typedef Right right_type;
301 
302  result_type operator()(left_type& left, const right_type& right) const {
303  using TiledArray::add_to;
305  add_to(left, right);
306  return cast(left);
307  }
308 };
309 
310 template <typename Result, typename Left, typename Right, typename Scalar,
311  typename Enabler = void>
312 class ScalAddTo {
313  public:
314  static_assert(TiledArray::detail::is_numeric_v<Scalar>,
315  "Cannot scale tiles by a non-scalar type");
316 
317  typedef Result result_type;
318  typedef Left left_type;
319  typedef Right right_type;
320  typedef Scalar scalar_type;
321 
322  result_type& operator()(left_type& left, const right_type& right) const {
323  using TiledArray::add_to;
324  return add_to(left, right);
325  }
326 };
327 
328 template <typename Result, typename Left, typename Right, typename Scalar>
329 class ScalAddTo<
330  Result, Left, Right, Scalar,
331  typename std::enable_if<!std::is_same<
332  Result, result_of_add_to_t<Left, Right, Scalar>>::value>::type> {
333  public:
334  static_assert(TiledArray::detail::is_numeric_v<Scalar>,
335  "Cannot scale tiles by a non-scalar type");
336 
337  typedef Result result_type;
338  typedef Left left_type;
339  typedef Right right_type;
340  typedef Scalar scalar_type;
341 
343  const scalar_type factor) const {
344  using TiledArray::add_to;
346  add_to(left, right);
347  return cast(left);
348  }
349 };
350 
351 } // namespace tile_interface
352 
354 
360 template <typename Result, typename Left, typename Right>
361 class Add : public TiledArray::tile_interface::Add<Result, Left, Right> {};
362 
364 
371 template <typename Result, typename Left, typename Right, typename Scalar>
372 class ScalAdd
373  : public TiledArray::tile_interface::ScalAdd<Result, Left, Right, Scalar> {
374 };
375 
377 
382 template <typename Result, typename Left, typename Right>
383 class AddTo : public TiledArray::tile_interface::AddTo<Result, Left, Right> {};
384 
386 
392 template <typename Result, typename Left, typename Right, typename Scalar>
394  Right, Scalar> {
395 };
396 
397 } // namespace TiledArray
398 
399 #endif // TILEDARRAY_TILE_INTERFACE_ADD_H__INCLUDED
Scalar scalar_type
The scaling factor type.
Definition: add.h:228
Add-to tile operation.
Definition: add.h:383
Right right_type
Right-hand argument tile type.
Definition: add.h:285
result_type & operator()(left_type &left, const right_type &right) const
Definition: add.h:287
Left left_type
Left-hand argument tile type.
Definition: add.h:284
result_type operator()(const left_type &left, const right_type &right, const Perm &perm) const
Definition: add.h:183
Scalar scalar_type
The scaling factor type.
Definition: add.h:320
Right right_type
Right-hand argument tile type.
Definition: add.h:319
Add tile operation.
Definition: add.h:361
Add tile operation.
Definition: add.h:373
decltype(auto) add(const Tile< Left > &left, const Tile< Right > &right)
Add tile arguments.
Definition: tile.h:734
Result result_type
Result tile type.
Definition: add.h:172
Left left_type
Left-hand argument tile type.
Definition: add.h:226
Tile cast operation.
Definition: cast.h:168
Right right_type
Right-hand argument tile type.
Definition: add.h:174
Tile< Result > & add_to(Tile< Result > &result, const Tile< Arg > &arg)
Add to the result tile.
Definition: tile.h:831
Add-to and scale tile operation.
Definition: add.h:394
Left left_type
Left-hand argument tile type.
Definition: add.h:173
Result result_type
Result tile type.
Definition: add.h:223
Result result_type
Result tile type.
Definition: add.h:283
Result result_type
Result tile type.
Definition: add.h:315
result_type & operator()(left_type &left, const right_type &right) const
Definition: add.h:322
decltype(add_to(std::declval< T >()...)) result_of_add_to_t
Definition: add.h:137
Left left_type
Left-hand argument tile type.
Definition: add.h:318
result_type operator()(const left_type &left, const right_type &right, const scalar_type factor) const
Definition: add.h:230
decltype(add(std::declval< T >()...)) result_of_add_t
Definition: add.h:134
Right right_type
Right-hand argument tile type.
Definition: add.h:227
result_type operator()(const left_type &left, const right_type &right) const
Definition: add.h:176
result_type operator()(const left_type &left, const right_type &right, const scalar_type factor, const Perm &perm) const
Definition: add.h:238