Vc  1.4.2
SIMD Vector Classes for C++
algorithms.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2013-2015 Matthias Kretz <kretz@kde.org>
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6  * Redistributions of source code must retain the above copyright
7  notice, this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright
9  notice, this list of conditions and the following disclaimer in the
10  documentation and/or other materials provided with the distribution.
11  * Neither the names of contributing organizations nor the
12  names of its contributors may be used to endorse or promote products
13  derived from this software without specific prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 }}}*/
27 
28 #ifndef VC_COMMON_ALGORITHMS_H_
29 #define VC_COMMON_ALGORITHMS_H_
30 
31 #include "simdize.h"
32 
33 namespace Vc_VERSIONED_NAMESPACE
34 {
35 #ifdef DOXYGEN
36 
63 template <class InputIt, class UnaryFunction>
64 UnaryFunction simd_for_each(InputIt first, InputIt last, UnaryFunction f);
65 #else
66 template <class InputIt, class UnaryFunction,
67  class ValueType = typename std::iterator_traits<InputIt>::value_type>
68 inline enable_if<
69  Traits::is_functor_argument_immutable<UnaryFunction, simdize<ValueType>>::value,
70  UnaryFunction>
71 simd_for_each(InputIt first, InputIt last, UnaryFunction f)
72 {
73  typedef simdize<ValueType> V;
74  typedef simdize<ValueType, 1> V1;
75  const auto lastV = last - V::Size + 1;
76  for (; first < lastV; first += V::Size) {
77  V tmp;
78  load_interleaved(tmp, std::addressof(*first));
79  f(tmp);
80  }
81  for (; first != last; ++first) {
82  V1 tmp;
83  load_interleaved(tmp, std::addressof(*first));
84  f(tmp);
85  }
86  return f;
87 }
88 
89 template <typename InputIt, typename UnaryFunction,
90  class ValueType = typename std::iterator_traits<InputIt>::value_type>
91 inline enable_if<
92  !Traits::is_functor_argument_immutable<UnaryFunction, simdize<ValueType>>::value,
93  UnaryFunction>
94 simd_for_each(InputIt first, InputIt last, UnaryFunction f)
95 {
96  typedef simdize<ValueType> V;
97  typedef simdize<ValueType, 1> V1;
98  const auto lastV = last - V::size() + 1;
99  for (; first < lastV; first += V::size()) {
100  V tmp;
101  load_interleaved(tmp, std::addressof(*first));
102  f(tmp);
103  store_interleaved(tmp, std::addressof(*first));
104  }
105  for (; first != last; ++first) {
106  V1 tmp;
107  load_interleaved(tmp, std::addressof(*first));
108  f(tmp);
109  store_interleaved(tmp, std::addressof(*first));
110  }
111  return f;
112 }
113 #endif
114 
116 template <typename InputIt, typename UnaryFunction,
117  class ValueType = typename std::iterator_traits<InputIt>::value_type>
118 inline enable_if<
119  Traits::is_functor_argument_immutable<UnaryFunction, simdize<ValueType>>::value,
120  UnaryFunction>
121 simd_for_each_n(InputIt first, std::size_t count, UnaryFunction f)
122 {
123  typename std::make_signed<size_t>::type len = count;
124  typedef simdize<ValueType> V;
125  typedef simdize<ValueType, 1> V1;
126  for (; len >= int(V::size()); len -= V::Size, first += V::Size) {
127  V tmp;
128  load_interleaved(tmp, std::addressof(*first));
129  f(tmp);
130  }
131  for (; len != 0; --len, ++first) {
132  V1 tmp;
133  load_interleaved(tmp, std::addressof(*first));
134  f(tmp);
135  }
136  return f;
137 }
138 
139 template <typename InputIt, typename UnaryFunction,
140  class ValueType = typename std::iterator_traits<InputIt>::value_type>
141 inline enable_if<
142  !Traits::is_functor_argument_immutable<UnaryFunction, simdize<ValueType>>::value,
143  UnaryFunction>
144 simd_for_each_n(InputIt first, std::size_t count, UnaryFunction f)
145 {
146  typename std::make_signed<size_t>::type len = count;
147  typedef simdize<ValueType> V;
148  typedef simdize<ValueType, 1> V1;
149  for (; len >= int(V::size()); len -= V::Size, first += V::Size) {
150  V tmp;
151  load_interleaved(tmp, std::addressof(*first));
152  f(tmp);
153  store_interleaved(tmp, std::addressof(*first));
154  }
155  for (; len != 0; --len, ++first) {
156  V1 tmp;
157  load_interleaved(tmp, std::addressof(*first));
158  f(tmp);
159  store_interleaved(tmp, std::addressof(*first));
160  }
161  return f;
162 }
163 
164 } // namespace Vc
165 
166 #endif // VC_COMMON_ALGORITHMS_H_
Vc::simd_for_each
UnaryFunction simd_for_each(InputIt first, InputIt last, UnaryFunction f)