Skip to content

Commit 8a4e028

Browse files
committed
optimization
1 parent cc0f528 commit 8a4e028

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

stl/inc/functional

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,46 @@ struct _Bit_xnor {
268268
using is_transparent = int;
269269
};
270270

271+
struct _Bit_imply {
272+
template <class _Ty1, class _Ty2>
273+
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const //
274+
-> decltype(~_STD forward<_Ty1>(_Left) | _STD forward<_Ty2>(_Right)) {
275+
return ~_STD forward<_Ty1>(_Left) | _STD forward<_Ty2>(_Right);
276+
}
277+
278+
using is_transparent = int;
279+
};
280+
281+
struct _Bit_cimply {
282+
template <class _Ty1, class _Ty2>
283+
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const //
284+
-> decltype(_STD forward<_Ty1>(_Left) | ~_STD forward<_Ty2>(_Right)) {
285+
return _STD forward<_Ty1>(_Left) | ~_STD forward<_Ty2>(_Right);
286+
}
287+
288+
using is_transparent = int;
289+
};
290+
291+
struct _Bit_nimply {
292+
template <class _Ty1, class _Ty2>
293+
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const //
294+
-> decltype(_STD forward<_Ty1>(_Left) & ~_STD forward<_Ty2>(_Right)) {
295+
return _STD forward<_Ty1>(_Left) & ~_STD forward<_Ty2>(_Right);
296+
}
297+
298+
using is_transparent = int;
299+
};
300+
301+
struct _Bit_cnimply {
302+
template <class _Ty1, class _Ty2>
303+
_NODISCARD constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const //
304+
-> decltype(~_STD forward<_Ty1>(_Left) & _STD forward<_Ty2>(_Right)) {
305+
return ~_STD forward<_Ty1>(_Left) & _STD forward<_Ty2>(_Right);
306+
}
307+
308+
using is_transparent = int;
309+
};
310+
271311
template <class _Ty>
272312
constexpr bool _Is_vbool_functor_arg = is_void_v<_Ty> || is_integral_v<_Ty>;
273313

@@ -306,6 +346,26 @@ struct _Map_vb_functor<equal_to<_Ty>> {
306346
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, _Bit_xnor, void>;
307347
};
308348

349+
template <class _Ty>
350+
struct _Map_vb_functor<less_equal<_Ty>> {
351+
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, _Bit_imply, void>;
352+
};
353+
354+
template <class _Ty>
355+
struct _Map_vb_functor<greater_equal<_Ty>> {
356+
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, _Bit_cimply, void>;
357+
};
358+
359+
template <class _Ty>
360+
struct _Map_vb_functor<less<_Ty>> {
361+
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, _Bit_cnimply, void>;
362+
};
363+
364+
template <class _Ty>
365+
struct _Map_vb_functor<greater<_Ty>> {
366+
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, _Bit_nimply, void>;
367+
};
368+
309369
template <class _Ty>
310370
struct _Map_vb_functor<logical_not<_Ty>> {
311371
using type = conditional_t<_Is_vbool_functor_arg<_Ty>, bit_not<>, void>;

tests/std/tests/GH_000625_vector_bool_optimization/test.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,20 @@ CONSTEXPR20 void test_transform_helper(const size_t length) {
7676
bool or_expected_raw[size(source_raw)];
7777
bool xor_expected_raw[size(source_raw)];
7878
bool xnor_expected_raw[size(source_raw)];
79+
bool l_expected_raw[size(source_raw)];
80+
bool le_expected_raw[size(source_raw)];
81+
bool g_expected_raw[size(source_raw)];
82+
bool ge_expected_raw[size(source_raw)];
7983
bool not_expected_raw[size(source_raw)];
8084

8185
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(and_expected_raw), logical_and<>{});
8286
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(or_expected_raw), logical_or<>{});
8387
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(xor_expected_raw), not_equal_to<>{});
8488
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(xnor_expected_raw), equal_to<>{});
89+
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(l_expected_raw), less<>{});
90+
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(le_expected_raw), less_equal<>{});
91+
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(g_expected_raw), greater<>{});
92+
transform(begin(source_raw), end(source_raw), begin(source2_raw), begin(ge_expected_raw), greater_equal<>{});
8593
transform(begin(source_raw), end(source_raw), begin(not_expected_raw), logical_not<>{});
8694

8795
const vector<bool> source1(source_raw, source_raw + length);
@@ -91,18 +99,30 @@ CONSTEXPR20 void test_transform_helper(const size_t length) {
9199
vector<bool> or_expected(or_expected_raw, or_expected_raw + length);
92100
vector<bool> xor_expected(xor_expected_raw, xor_expected_raw + length);
93101
vector<bool> xnor_expected(xnor_expected_raw, xnor_expected_raw + length);
102+
vector<bool> less_expected(l_expected_raw, l_expected_raw + length);
103+
vector<bool> less_equal_expected(le_expected_raw, le_expected_raw + length);
104+
vector<bool> greater_expected(g_expected_raw, g_expected_raw + length);
105+
vector<bool> greater_equal_expected(ge_expected_raw, ge_expected_raw + length);
94106
vector<bool> not_expected(not_expected_raw, not_expected_raw + length);
95107

96108
and_expected.resize(length + 3, false);
97109
or_expected.resize(length + 3, false);
98110
xor_expected.resize(length + 3, false);
99111
xnor_expected.resize(length + 3, false);
112+
less_expected.resize(length + 3, false);
113+
less_equal_expected.resize(length + 3, false);
114+
greater_expected.resize(length + 3, false);
115+
greater_equal_expected.resize(length + 3, false);
100116
not_expected.resize(length + 3, false);
101117

102118
vector<bool> and_actual(length + 3);
103119
vector<bool> or_actual(length + 3);
104120
vector<bool> xor_actual(length + 3);
105121
vector<bool> xnor_actual(length + 3);
122+
vector<bool> less_actual(length + 3);
123+
vector<bool> less_equal_actual(length + 3);
124+
vector<bool> greater_actual(length + 3);
125+
vector<bool> greater_equal_actual(length + 3);
106126
vector<bool> not_actual(length + 3);
107127

108128
// Also test combinations of vector<bool>::iterator and vector<bool>::const_iterator for the inputs.
@@ -157,6 +177,30 @@ CONSTEXPR20 void test_transform_helper(const size_t length) {
157177
// bit_xnor doesn't exist in the Standard
158178
}
159179

180+
{
181+
const auto less_ret = transform(cfirst1, clast1, cfirst2, less_actual.begin(), less<>{});
182+
assert(less_actual == less_expected);
183+
assert(less_ret == less_actual.begin() + length);
184+
}
185+
186+
{
187+
const auto less_equal_ret = transform(cfirst1, clast1, cfirst2, less_equal_actual.begin(), less_equal<>{});
188+
assert(less_equal_actual == less_equal_expected);
189+
assert(less_equal_ret == less_equal_actual.begin() + length);
190+
}
191+
192+
{
193+
const auto greater_ret = transform(cfirst1, clast1, cfirst2, greater_actual.begin(), greater<>{});
194+
assert(greater_actual == greater_expected);
195+
assert(greater_ret == greater_actual.begin() + length);
196+
}
197+
198+
{
199+
const auto greater_equal_ret = transform(cfirst1, clast1, cfirst2, greater_equal_actual.begin(), greater_equal<>{});
200+
assert(greater_equal_actual == greater_equal_expected);
201+
assert(greater_equal_ret == greater_equal_actual.begin() + length);
202+
}
203+
160204
{
161205
auto not_ret = transform(first1, last1, not_actual.begin(), logical_not<>{});
162206
assert(not_actual == not_expected);

0 commit comments

Comments
 (0)