Skip to content

Commit

Permalink
fix violation of deprecated-declarations in Range
Browse files Browse the repository at this point in the history
Summary:
`Range` uses `std::char_traits` over all its param types, which does not conform.

Unblocks Xcode 15.

Fixes the following report:
```
folly/Range.h:197:12: error: 'char_traits<unsigned char>' is deprecated: char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it. [-Werror,-Wdeprecated-declarations]
      std::char_traits<typename std::remove_const<value_type>::type>;
           ^
folly/Range.h:110:20: note: in instantiation of template class 'folly::Range<const unsigned char *>' requested here
    const typename Range<Iter>::value_type& needle);
                   ^
folly/Range.h:1495:15: note: while substituting deduced template arguments into function template 'qfind' [with Iter = const unsigned char *]
inline size_t qfind(
              ^
```

Reviewed By: NSProgrammer

Differential Revision: D46823611

fbshipit-source-id: 0f27b26ecd6d4f48ef210c126f1f502597e8903b
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Jun 18, 2023
1 parent 9079e21 commit 45fffa6
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
75 changes: 73 additions & 2 deletions folly/Range.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include <folly/Traits.h>
#include <folly/detail/RangeCommon.h>
#include <folly/detail/RangeSse42.h>
#include <folly/lang/Byte.h>

// Ignore shadowing warnings within this file, so includers can use -Wshadow.
FOLLY_PUSH_WARNING
Expand Down Expand Up @@ -164,6 +165,75 @@ struct IsUnsignedCharPointer<const unsigned char*> {
using type = int;
};

void range_is_char_type_f_(char const*);
void range_is_char_type_f_(wchar_t const*);
#if (defined(__cpp_char8_t) && __cpp_char8_t >= 201811L) || \
FOLLY_CPLUSPLUS >= 202002
void range_is_char_type_f_(char8_t const*);
#endif
void range_is_char_type_f_(char16_t const*);
void range_is_char_type_f_(char32_t const*);
template <typename Iter>
using range_is_char_type_d_ =
decltype(folly::detail::range_is_char_type_f_(FOLLY_DECLVAL(Iter)));
template <typename Iter>
constexpr bool range_is_char_type_v_ =
is_detected_v<range_is_char_type_d_, Iter>;

void range_is_byte_type_f_(unsigned char const*);
void range_is_byte_type_f_(signed char const*);
void range_is_byte_type_f_(byte const*);
template <typename Iter>
using range_is_byte_type_d_ =
decltype(folly::detail::range_is_byte_type_f_(FOLLY_DECLVAL(Iter)));
template <typename Iter>
constexpr bool range_is_byte_type_v_ =
is_detected_v<range_is_byte_type_d_, Iter>;

struct range_traits_char_ {
template <typename Value>
using apply = std::char_traits<Value>;
};
struct range_traits_byte_ {
template <typename Value>
struct apply {
FOLLY_ERASE static constexpr int compare(
Value const* a, Value const* b, std::size_t c) {
return !c ? 0 : std::memcmp(a, b, c);
}
};
};
struct range_traits_fbck_ {
template <typename Value>
struct apply {
FOLLY_ERASE static constexpr int compare(
Value const* a, Value const* b, std::size_t c) {
while (c--) {
auto&& ai = *a++;
auto&& bi = *b++;
if (ai < bi) {
return -1;
}
if (bi < ai) {
return +1;
}
}
return 0;
}
};
};

template <typename Iter>
using range_traits_c_ = conditional_t<
range_is_char_type_v_<Iter>,
range_traits_char_,
conditional_t< //
range_is_byte_type_v_<Iter>,
range_traits_byte_,
range_traits_fbck_>>;
template <typename Iter, typename Value>
using range_traits_t_ = typename range_traits_c_<Iter>::template apply<Value>;

} // namespace detail

template <class Iter>
Expand Down Expand Up @@ -193,8 +263,9 @@ class Range {
Range<const value_type*>,
Range<Iter>>::type;

using traits_type =
std::char_traits<typename std::remove_const<value_type>::type>;
using traits_type = detail::range_traits_t_< //
Iter,
typename std::remove_const<value_type>::type>;

static const size_type npos;

Expand Down
38 changes: 38 additions & 0 deletions folly/test/RangeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ CPP_assert(ranges::view_<folly::StringPiece>);
using namespace folly;
using namespace std;

static_assert(folly::detail::range_is_char_type_v_<char*>, "");
static_assert(folly::detail::range_is_byte_type_v_<unsigned char*>, "");

static_assert(std::is_literal_type<StringPiece>::value, "");

BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<StringPiece>));
Expand Down Expand Up @@ -1257,6 +1260,41 @@ TEST(CRangeFunc, Collection) {
EXPECT_THAT(numCollRange, testing::ElementsAreArray({17, 1}));
}

TEST(Range, CompareChar) {
EXPECT_EQ(""_sp, ""_sp);
EXPECT_LT(""_sp, "world"_sp);
EXPECT_GT("world"_sp, ""_sp);
EXPECT_EQ("hello"_sp, "hello"_sp);
EXPECT_LT("hello"_sp, "world"_sp);
EXPECT_LT("hello"_sp, "helloworld"_sp);
EXPECT_GT("world"_sp, "hello"_sp);
EXPECT_GT("helloworld"_sp, "hello"_sp);
}

TEST(Range, CompareByte) {
auto br = [](auto sp) { return ByteRange(sp); };
EXPECT_EQ(br(""_sp), br(""_sp));
EXPECT_LT(br(""_sp), br("world"_sp));
EXPECT_GT(br("world"_sp), br(""_sp));
EXPECT_EQ(br("hello"_sp), br("hello"_sp));
EXPECT_LT(br("hello"_sp), br("world"_sp));
EXPECT_LT(br("hello"_sp), br("helloworld"_sp));
EXPECT_GT(br("world"_sp), br("hello"_sp));
EXPECT_GT(br("helloworld"_sp), br("hello"_sp));
}

TEST(Range, CompareFbck) {
auto vr = [](std::vector<int> const& _) { return folly::range(_); };
EXPECT_EQ(vr({}), vr({}));
EXPECT_LT(vr({}), vr({1}));
EXPECT_GT(vr({1}), vr({}));
EXPECT_EQ(vr({1}), vr({1}));
EXPECT_LT(vr({1}), vr({2}));
EXPECT_LT(vr({1}), vr({1, 2}));
EXPECT_GT(vr({2}), vr({1}));
EXPECT_GT(vr({1, 1}), vr({1}));
}

std::string get_rand_str(
size_t size, std::uniform_int_distribution<>& dist, std::mt19937& gen) {
std::string ret(size, '\0');
Expand Down

0 comments on commit 45fffa6

Please sign in to comment.