Correct behavior for classes for which only lvalue is convertible to string_view.

Added OnlyLValueString test case that shows the problem with
current impl. Implemented the change, that accept TimeZonePtrOrName
by forwarding reference (to preserve value category), and
merged time_zone selection into one trait.
This commit is contained in:
Tomasz Kamiński 2019-08-06 08:57:50 +02:00 committed by Howard Hinnant
parent 5345d135b7
commit 5a0057587d
2 changed files with 37 additions and 32 deletions

View File

@ -709,6 +709,18 @@ using zoned_seconds = zoned_time<std::chrono::seconds>;
#if HAS_DEDUCTION_GUIDES
namespace detail
{
template<typename TimeZonePtrOrName>
using time_zone_representation =
std::conditional_t
<
std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
time_zone const*,
std::remove_cv_t<std::remove_reference_t<TimeZonePtrOrName>>
>;
}
zoned_time()
-> zoned_time<std::chrono::seconds>;
@ -717,44 +729,20 @@ zoned_time(sys_time<Duration>)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>>;
template <class TimeZonePtrOrName>
zoned_time(TimeZonePtrOrName)
-> zoned_time<std::chrono::seconds,
std::conditional_t
<
std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
time_zone const*,
TimeZonePtrOrName
>>;
zoned_time(TimeZonePtrOrName&&)
-> zoned_time<std::chrono::seconds, detail::time_zone_representation<TimeZonePtrOrName>>;
template <class TimeZonePtrOrName, class Duration>
zoned_time(TimeZonePtrOrName, sys_time<Duration>)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>,
std::conditional_t
<
std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
time_zone const*,
TimeZonePtrOrName
>>;
zoned_time(TimeZonePtrOrName&&, sys_time<Duration>)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
template <class TimeZonePtrOrName, class Duration>
zoned_time(TimeZonePtrOrName, local_time<Duration>, choose = choose::earliest)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>,
std::conditional_t
<
std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
time_zone const*,
TimeZonePtrOrName
>>;
zoned_time(TimeZonePtrOrName&&, local_time<Duration>, choose = choose::earliest)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
template <class Duration, class TimeZonePtrOrName, class TimeZonePtr2>
zoned_time(TimeZonePtrOrName, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>,
std::conditional_t
<
std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
time_zone const*,
TimeZonePtrOrName
>>;
zoned_time(TimeZonePtrOrName&&, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
-> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
#endif // HAS_DEDUCTION_GUIDES

View File

@ -127,6 +127,15 @@ private:
std::string ms;
};
struct OnlyLValueString
{
OnlyLValueString(std::string s) : ms(std::move(s)) {}
operator std::string_view() & { return ms; }
private:
std::string ms;
};
#endif // HAS_DEDUCTION_GUIDES
@ -225,5 +234,13 @@ main()
testDeductionFrom<OffsetZone>(std::move(tz));
}
// OnlyLValue
{
OnlyLValueString tz("Europe/Warsaw");
testDeductionFrom<time_zone const*>(tz);
//testDeductionFrom<time_zone const*>(to_const(tz));
//testDeductionFrom<time_zone const*>(std::move(tz));
}
#endif // HAS_DEDUCTION_GUIDES
}