This is an archive of the discontinued LLVM Phabricator instance.

[libc++][ranges] Add implicit conversion to bool test for ranges::find{, if, if_not}
ClosedPublic

Authored by philnik on Mar 18 2022, 8:24 AM.

Diff Detail

Event Timeline

philnik created this revision.Mar 18 2022, 8:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 18 2022, 8:24 AM
philnik requested review of this revision.Mar 18 2022, 8:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 18 2022, 8:24 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne added inline comments.Mar 18 2022, 8:50 AM
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp
225–227

WDYT? IMO this clarifies exactly what we're testing.

libcxx/test/support/immobile_bool.h
1 ↗(On Diff #416515)

How about BooleanTestable, since this is roughly an archetype for being boolean-testable?

ldionne added inline comments.Mar 18 2022, 9:05 AM
libcxx/test/support/immobile_bool.h
1 ↗(On Diff #416515)

Actually, here's what I came up with after discussing with you offline and playing around with the patch:

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
#define LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H

struct BooleanTestable {
  constexpr operator bool() {
    return value_;
  }

  constexpr BooleanTestable(bool value) : value_{value} {}
  BooleanTestable(const BooleanTestable&) = delete;
  BooleanTestable(BooleanTestable&&) = delete;

private:
  bool value_;
};

template <typename T>
struct StrictComparable {
  constexpr StrictComparable(T value) : value_(value) { }

  friend constexpr BooleanTestable operator==(StrictComparable const& a, StrictComparable const& b) {
    return BooleanTestable(a.value_ == b.value_);
  }
  friend constexpr BooleanTestable operator!=(StrictComparable const& a, StrictComparable const& b) {
    return BooleanTestable(a.value_ != b.value_);
  }

private:
  T value_;
};

#endif // LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H

Then you can use it as:

{
    StrictComparable<int> a[] = {1, 2, 3, 4};
    auto ret = std::ranges::find(a, a + 4, StrictComparable<int>{4});
    assert(ret == a + 3);
}
{
    StrictComparable<int> a[] = {1, 2, 3, 4};
    auto ret = std::ranges::find(a, StrictComparable<int>{4});
    assert(ret == a + 3);
}

I'm not a big fan of the name StrictComparable, but I like that we're not mixing up the type in the range and the boolean testable archetype.

var-const added inline comments.Mar 21 2022, 10:53 PM
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp
232

Can you add an explicit return type to make it clear that we're also testing that the algorithm supports predicates that return something convertible to bool, not just bool? (assuming I'm understanding the intention correctly) Applies to find_if_not as well.

philnik updated this revision to Diff 418838.Mar 29 2022, 4:25 AM
philnik marked 4 inline comments as done.
  • Address comments
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp
232

I think this comment doesn't apply anymore. LMK if I'm wrong.

Mordante added inline comments.Mar 30 2022, 9:08 AM
libcxx/test/support/boolean_testable.h
15

This header needs to be guarded with the proper C++ version.

var-const added inline comments.Apr 1 2022, 9:45 PM
libcxx/test/support/boolean_testable.h
15

Nit: can this function be const?

23

Do we need this class to work pre-C++20?

27

I presume this constructor intentionally allows implicit conversions, can you please mention that in a comment (assuming it's true)? Applies to StrictComparable as well.

32

Optional: = false?

philnik updated this revision to Diff 419936.Apr 1 2022, 10:45 PM
philnik marked 4 inline comments as done.
  • Address comments
libcxx/test/support/boolean_testable.h
23

No, but the operator!= only gets implicitly generated if the return value of operator== is bool. Things only compilers know :D.

32

Why? This class only has a single constructor which always sets the value. In this case I think it's more confusing than helpful.

var-const accepted this revision as: var-const.Apr 1 2022, 10:55 PM
var-const added inline comments.
libcxx/test/support/boolean_testable.h
23

Interesting -- might be worth adding a comment, actually (but very optional).

32

Personally, I find it easier because a) I don't need to read through the constructors to make sure this primitive is always initialized, and b) it can prevent bugs (which are easy to fix but still take some unnecessary time) when adding a default constructor later. But if you prefer the current state, please keep as is.

45

Nit: s/initlaizer/initialize/ (or perhaps it should be something like use as an initializer?).

ldionne accepted this revision.Apr 6 2022, 11:21 AM

LGTM but please address Costa's comments.

This revision is now accepted and ready to land.Apr 6 2022, 11:21 AM
This revision was landed with ongoing or failed builds.Apr 7 2022, 3:04 AM
This revision was automatically updated to reflect the committed changes.
philnik marked an inline comment as done.