`ranges::begin/rbegin/data` can be used on non-ranges as long as the object has a `begin/rbegin/data` member, this is also true for their const versions before C++23.
However, in C++23 the const version always applied possibly-const-range
to the object,
which no longer worked for non-ranges due to this function requiring `input_range`,
which seems to be a breaking change (demo):
#include <ranges>
struct NotRange {
int* begin();
const int* begin() const;
int* rbegin();
const int* rbegin() const;
int* data();
const int* data() const;
};
int main() {
NotRange r;
(void) std::ranges::begin(r);
(void) std::ranges::rbegin(r);
(void) std::ranges::data(r);
// The following works in C++20, fails in C++23
(void) std::ranges::cbegin(r);
(void) std::ranges::crbegin(r);
(void) std::ranges::cdata(r);
}