Commit 23020412 authored by Mark Santaniello's avatar Mark Santaniello Committed by Facebook Github Bot

Make folly::Range more permissive of incomplete types

Summary: Defer evaluation so that conversion operator value_type can be incomplete.

Reviewed By: yfeldblum, nbronson

Differential Revision: D13123972

fbshipit-source-id: b53431232d20b2962530ad9ad81ed12acb5d7208
parent 9a7456e6
...@@ -497,15 +497,21 @@ class Range { ...@@ -497,15 +497,21 @@ class Range {
// std::string_view (when it is available). // std::string_view (when it is available).
#if FOLLY_HAS_STRING_VIEW #if FOLLY_HAS_STRING_VIEW
struct NotStringView {}; struct NotStringView {};
using StringViewType = std::conditional_t< template <typename ValueType>
std::is_pod<std::remove_const_t<value_type>>::value, struct StringViewType
std::basic_string_view<std::remove_const_t<value_type>>, : std::conditional<
NotStringView>; std::is_pod<std::remove_const_t<ValueType>>::value,
std::basic_string_view<std::remove_const_t<ValueType>>,
NotStringView> {};
template <typename Target> template <typename Target>
using IsConstructibleViaStringView = StrictConjunction< struct IsConstructibleViaStringView
std::is_constructible<StringViewType, Iter const&, size_type>, : Conjunction<
std::is_constructible<Target, StringViewType>>; std::is_constructible<
_t<StringViewType<value_type>>,
Iter const&,
size_type>,
std::is_constructible<Target, _t<StringViewType<value_type>>>> {};
#else #else
template <typename Target> template <typename Target>
using IsConstructibleViaStringView = std::false_type; using IsConstructibleViaStringView = std::false_type;
...@@ -545,11 +551,14 @@ class Range { ...@@ -545,11 +551,14 @@ class Range {
/// implicit operator conversion to std::string_view /// implicit operator conversion to std::string_view
template < template <
typename Tgt, typename Tgt,
typename ValueType = value_type,
std::enable_if_t< std::enable_if_t<
StrictConjunction< StrictConjunction<
std::is_same<Tgt, StringViewType>, std::is_same<Tgt, _t<StringViewType<ValueType>>>,
std::is_constructible<StringViewType, Iter const&, size_type>>:: std::is_constructible<
value, _t<StringViewType<ValueType>>,
Iter const&,
size_type>>::value,
int> = 0> int> = 0>
constexpr operator Tgt() const noexcept( constexpr operator Tgt() const noexcept(
std::is_nothrow_constructible<Tgt, Iter const&, size_type>::value) { std::is_nothrow_constructible<Tgt, Iter const&, size_type>::value) {
......
...@@ -1633,3 +1633,10 @@ void test_func(Range<const NonPOD*>) {} ...@@ -1633,3 +1633,10 @@ void test_func(Range<const NonPOD*>) {}
} // anonymous namespace } // anonymous namespace
#endif #endif
namespace {
// Nested class should not cause compile errors due to incomplete parent
class Parent {
struct Nested : Range<const Parent*> {};
};
} // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment