RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
foldl.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_foldl_HPP
21 #define RAJA_foldl_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <cstdint>
26 #include <functional>
27 #include <iostream>
28 #include <type_traits>
29 #include <utility>
30 
31 #include "camp/camp.hpp"
32 
33 #include "RAJA/util/macros.hpp"
34 
35 namespace RAJA
36 {
37 
38 // Basics, using c++14 semantics in a c++11 compatible way, credit to libc++
39 
40 // Forward
41 namespace detail
42 {
43 // FoldL
44 template<typename Op, typename... Rest>
45 struct foldl_impl;
46 
47 template<typename Op, typename Arg1>
48 struct foldl_impl<Op, Arg1>
49 {
50  using Ret = Arg1;
51 };
52 
53 #if RAJA_HAS_CXX17_IS_INVOCABLE
54 
55 template<typename Op, typename Arg1, typename Arg2>
56 struct foldl_impl<Op, Arg1, Arg2>
57 {
58  using Ret = typename std::invoke_result<Op, Arg1, Arg2>::type;
59 };
60 
61 template<typename Op,
62  typename Arg1,
63  typename Arg2,
64  typename Arg3,
65  typename... Rest>
66 struct foldl_impl<Op, Arg1, Arg2, Arg3, Rest...>
67 {
68  using Ret =
69  typename foldl_impl<Op,
70  typename std::invoke_result<
71  Op,
72  typename std::invoke_result<Op, Arg1, Arg2>::type,
73  Arg3>::type,
74  Rest...>::Ret;
75 };
76 
77 #else
78 
79 template<typename Op, typename Arg1, typename Arg2>
80 struct foldl_impl<Op, Arg1, Arg2>
81 {
82  using Ret = typename std::result_of<Op(Arg1, Arg2)>::type;
83 };
84 
85 template<typename Op,
86  typename Arg1,
87  typename Arg2,
88  typename Arg3,
89  typename... Rest>
90 struct foldl_impl<Op, Arg1, Arg2, Arg3, Rest...>
91 {
92  using Ret = typename foldl_impl<
93  Op,
94  typename std::result_of<Op(typename std::result_of<Op(Arg1, Arg2)>::type,
95  Arg3)>::type,
96  Rest...>::Ret;
97 };
98 
99 #endif
100 
101 } // namespace detail
102 
103 template<typename Op, typename Arg1>
104 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto foldl(
105  Op&& RAJA_UNUSED_ARG(operation),
106  Arg1&& arg) -> typename detail::foldl_impl<Op, Arg1>::Ret
107 {
108  return camp::forward<Arg1>(arg);
109 }
110 
111 template<typename Op, typename Arg1, typename Arg2>
112 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto foldl(Op&& operation,
113  Arg1&& arg1,
114  Arg2&& arg2) ->
116 {
117  return camp::forward<Op>(operation)(camp::forward<Arg1>(arg1),
118  camp::forward<Arg2>(arg2));
119 }
120 
121 template<typename Op,
122  typename Arg1,
123  typename Arg2,
124  typename Arg3,
125  typename... Rest>
126 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto foldl(Op&& operation,
127  Arg1&& arg1,
128  Arg2&& arg2,
129  Arg3&& arg3,
130  Rest&&... rest) ->
131  typename detail::foldl_impl<Op, Arg1, Arg2, Arg3, Rest...>::Ret
132 {
133  return foldl(camp::forward<Op>(operation),
134  camp::forward<Op>(operation)(
135  camp::forward<Op>(operation)(camp::forward<Arg1>(arg1),
136  camp::forward<Arg2>(arg2)),
137  camp::forward<Arg3>(arg3)),
138  camp::forward<Rest>(rest)...);
139 }
140 
141 // Convenience folds
142 template<typename Result, typename... Args>
143 RAJA_HOST_DEVICE RAJA_INLINE constexpr Result sum(Args... args)
144 {
146 }
147 
148 template<typename Result, typename... Args>
149 RAJA_HOST_DEVICE RAJA_INLINE constexpr Result product(Args... args)
150 {
152 }
153 
154 template<typename Result, typename... Args>
155 RAJA_HOST_DEVICE RAJA_INLINE constexpr Result max(Args... args)
156 {
158 }
159 
160 template<typename Result, typename... Args>
161 RAJA_HOST_DEVICE RAJA_INLINE constexpr Result min(Args... args)
162 {
164 }
165 
166 
167 } // namespace RAJA
168 
169 #endif
Header file for common RAJA internal macro definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
#define RAJA_UNUSED_ARG(x)
Definition: macros.hpp:97
Args args
Definition: WorkRunner.hpp:212
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result product(Args... args)
Definition: foldl.hpp:149
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result min(Args... args)
Definition: foldl.hpp:161
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result sum(Args... args)
Definition: foldl.hpp:143
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto foldl(Op &&RAJA_UNUSED_ARG(operation), Arg1 &&arg) -> typename detail::foldl_impl< Op, Arg1 >::Ret
Definition: foldl.hpp:104
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result max(Args... args)
Definition: foldl.hpp:155
typename foldl_impl< Op, typename std::result_of< Op(typename std::result_of< Op(Arg1, Arg2)>::type, Arg3)>::type, Rest... >::Ret Ret
Definition: foldl.hpp:96
typename std::result_of< Op(Arg1, Arg2)>::type Ret
Definition: foldl.hpp:82
Arg1 Ret
Definition: foldl.hpp:50
Definition: foldl.hpp:45
Definition: Operators.hpp:580
Definition: Operators.hpp:559
Definition: Operators.hpp:400
Definition: Operators.hpp:367