VCTR
Loading...
Searching...
No Matches
Clamp.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr::expressions
24{
25
26template <size_t extent, class SrcType, is::constantWithType<bool> ClampLow, is::constantWithType<bool> ClampHigh>
28{
29public:
30 using value_type = ValueType<SrcType>;
31
32 VCTR_COMMON_UNARY_EXPRESSION_MEMBERS (Clamp, src)
33
34 static constexpr bool clampLow = ClampLow::value;
35 static constexpr bool clampHigh = ClampHigh::value;
36
37 void applyRuntimeArgs (value_type newLowerBound, value_type newUpperBound)
38 {
39 lowerBound = newLowerBound;
40 upperBound = newUpperBound;
41 }
42
43 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
44 {
45 assertBoundsAreSet();
46
47 if constexpr (clampLow && clampHigh)
48 return std::clamp (src[i], lowerBound, upperBound);
49
50 if constexpr (clampLow && ! clampHigh)
51 return std::max (src[i], lowerBound);
52
53 if constexpr (! clampLow && clampHigh)
54 return std::min (src[i], upperBound);
55 }
56
57 //==============================================================================
58 // Platform Vector Operation Implementation
59 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
61 {
62 assertBoundsAreSet();
63
64 if constexpr (clampLow && ! clampHigh)
65 Expression::Accelerate::clampLow (src.evalNextVectorOpInExpressionChain (dst), lowerBound, dst, size());
66
67 if constexpr (clampHigh)
68 {
69 auto l = clampLow ? lowerBound : std::numeric_limits<value_type>::lowest();
70 Expression::Accelerate::clamp (src.evalNextVectorOpInExpressionChain (dst), l, upperBound, dst, size());
71 }
72
73 return dst;
74 }
75
76 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
78 {
79 assertBoundsAreSet();
80 const auto* s = src.evalNextVectorOpInExpressionChain (dst);
81
82 if constexpr (clampLow)
83 {
84 Expression::IPP::clampLow (s, lowerBound, dst, sizeToInt (size()));
85
86 if constexpr (clampHigh)
87 s = dst;
88 }
89
90 if constexpr (clampHigh)
91 Expression::IPP::clampHigh (s, upperBound, dst, sizeToInt (size()));
92
93 return dst;
94 }
95
96private:
97 void assertBoundsAreSet() const
98 {
99 // If you hit one of the assertions here, applyRuntimeArgs has not been called as expected.
100 // This should not happen under normal circumstances
101 if constexpr (clampLow)
102 VCTR_ASSERT (lowerBound != std::numeric_limits<value_type>::max());
103
104 if constexpr (clampHigh)
105 VCTR_ASSERT (upperBound != std::numeric_limits<value_type>::max());
106 }
107
108 value_type lowerBound = std::numeric_limits<value_type>::max();
109 value_type upperBound = std::numeric_limits<value_type>::max();
110};
111
112template <size_t extent, class SrcType>
114
115template <size_t extent, class SrcType>
117
118template <size_t extent, class SrcType>
120
121template <size_t extent, class SrcType, is::constant LowerBound, is::constant UpperBound>
123{
124public:
125 using value_type = ValueType<SrcType>;
126
127 static constexpr value_type lowerBound = LowerBound::value;
128 static constexpr value_type upperBound = UpperBound::value;
129
130 static constexpr bool clampLow = ! is::disabledConstant<LowerBound>;
131 static constexpr bool clampHigh = ! is::disabledConstant<UpperBound>;
132
133 VCTR_COMMON_UNARY_EXPRESSION_MEMBERS (ClampByConstant, src)
134
135 VCTR_FORCEDINLINE constexpr value_type operator[] (size_t i) const
136 {
137 if constexpr (clampLow && clampHigh)
138 return std::clamp (src[i], lowerBound, upperBound);
139
140 if constexpr (clampLow && ! clampHigh)
141 return std::max (src[i], lowerBound);
142
143 if constexpr (! clampLow && clampHigh)
144 return std::min (src[i], upperBound);
145
146 return std::max (lowerBound, src[i]);
147 }
148
149 //==============================================================================
150 // Platform Vector Operation Implementation
151 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
153 {
154 if constexpr (clampLow && ! clampHigh)
155 Expression::Accelerate::clampLow (src.evalNextVectorOpInExpressionChain (dst), lowerBound, dst, size());
156
157 if constexpr (clampHigh)
158 {
159 auto l = clampLow ? lowerBound : std::numeric_limits<value_type>::lowest();
160 Expression::Accelerate::clamp (src.evalNextVectorOpInExpressionChain (dst), l, upperBound, dst, size());
161 }
162
163 return dst;
164 }
165
166 VCTR_FORCEDINLINE const value_type* evalNextVectorOpInExpressionChain (value_type* dst) const
168 {
169 const auto* s = src.evalNextVectorOpInExpressionChain (dst);
170
171 if constexpr (clampLow)
172 {
173 Expression::IPP::clampLow (s, lowerBound, dst, sizeToInt (size()));
174
175 if constexpr (clampHigh)
176 s = dst;
177 }
178
179 if constexpr (clampHigh)
180 Expression::IPP::clampHigh (s, upperBound, dst, sizeToInt (size()));
181
182 return dst;
183 }
184};
185
186} // namespace vctr::expressions
187
188namespace vctr
189{
190
198template <class T>
199constexpr auto clampLow (T lowerBound)
200{
201 return makeExpressionChainBuilderWithRuntimeArgs<expressions::ClampLow> (lowerBound, std::numeric_limits<T>::max());
202}
203
211template <class T>
212constexpr auto clampHigh (T upperBound)
213{
214 return makeExpressionChainBuilderWithRuntimeArgs<expressions::ClampHigh> (std::numeric_limits<T>::max(), upperBound);
215}
216
224template <class T>
225constexpr auto clamp (T lowerBound, T upperBound)
226{
227 return makeExpressionChainBuilderWithRuntimeArgs<expressions::ClampLowHigh> (lowerBound, upperBound);
228}
229
230
231
240template <auto lowerBound>
242
251template <auto upperBound>
253
262template <auto lowerBound, auto upperBound>
264
265} // namespace vctr
Definition: Clamp.h:123
Definition: Clamp.h:28
Constrains a type to be of the type DisabledConstant.
Definition: NumericTypeConcepts.h:91
A combined concept to check if Apple Accelerate is a suitable option for a real valued floating point...
Definition: ContainerAndExpressionConcepts.h:242
A combined concept to check if Intel IPP is a suitable option for a real valued floating point vector...
Definition: ContainerAndExpressionConcepts.h:266
constexpr ExpressionChainBuilder< expressions::ClampByConstant, DisabledConstant, Constant< upperBound > > clampHighByConstant
Ensures that the elements are not higher than upperBound.
Definition: Clamp.h:252
constexpr auto clampLow(T lowerBound)
Ensures that the elements are not lower than lowerBound.
Definition: Clamp.h:199
constexpr ExpressionChainBuilder< expressions::ClampByConstant, Constant< lowerBound >, Constant< upperBound > > clampByConstant
Ensures that the elements are not lower than lowerBound and not higher than upperBound.
Definition: Clamp.h:263
constexpr auto clampHigh(T upperBound)
Ensures that the elements are not greater than upperBound.
Definition: Clamp.h:212
constexpr ExpressionChainBuilder< expressions::ClampByConstant, Constant< lowerBound >, DisabledConstant > clampLowByConstant
Ensures that the elements are not lower than lowerBound.
Definition: Clamp.h:241
constexpr auto clamp(T lowerBound, T upperBound)
Ensures that the elements are not lower than lowerBound and not higher than upperBound.
Definition: Clamp.h:225
The main namespace of the VCTR project.
Definition: Array.h:24
typename detail::ValueType< std::remove_cvref_t< T > >::Type ValueType
If T is an expression template, it equals its return type, if it's a type that defines value_type as ...
Definition: Traits.h:201
int sizeToInt(size_t size)
Casts the size_t argument to an int.
Definition: PlatformVectorOpsHelpers.h:27
A simple helper struct to pass a constant as argument wrapped in a struct with a single public static...
Definition: ExpressionChainBuilder.h:104
A helper struct to indicate that a constant template should be considered disabled.
Definition: ExpressionChainBuilder.h:110
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:136
The base class to every expression template.
Definition: ExpressionTemplate.h:37