@@ -483,9 +483,9 @@ struct unique
483483 public:
484484 constexpr modifier () = default;
485485 modifier (const modifier&) = delete ;
486- constexpr modifier (modifier&&) = default;
486+ constexpr modifier (modifier&&) noexcept = default;
487487 modifier& operator =(const modifier&) = delete ;
488- constexpr modifier& operator =(modifier&&) = default ;
488+ constexpr modifier& operator =(modifier&&) noexcept = default ;
489489 };
490490};
491491struct ordered
@@ -1595,10 +1595,13 @@ struct implicitly_convertible_to
15951595
15961596struct formattable
15971597{
1598- template <typename T>
1599- class modifier {};
1598+ template <typename T>
1599+ class modifier {};
16001600};
16011601
1602+ template <typename T>
1603+ using is_formattable = std::is_base_of<formattable::modifier<T>, T>;
1604+
16021605}
16031606
16041607namespace std {
@@ -1628,58 +1631,83 @@ struct hash<::strong::type<T, Tag, M...>>
16281631
16291632#if STRONG_HAS_STD_FORMAT
16301633template <typename T, typename Tag, typename ... M, typename Char>
1631- struct formatter <::strong::type<T, Tag, M...>, Char>
1632- : std::enable_if_t <
1633- std::is_base_of<
1634- ::strong::formattable::modifier<
1635- ::strong::type<T, Tag, M...>
1636- >,
1637- ::strong::type<T, Tag, M...>
1638- >::value,
1639- formatter<T>
1640- >
1634+ requires std::is_base_of_v<::strong::formattable::modifier<::strong::type<T, Tag, M...>>,
1635+ ::strong::type<T, Tag, M...>>
1636+ struct formatter <::strong::type<T, Tag, M...>, Char> : formatter<T, Char>
16411637{
1642- using type = ::strong::type<T, Tag, M...>;
1643- template <typename FormatContext>
1638+ template <typename FormatContext, typename Type>
16441639 STRONG_CONSTEXPR
16451640 decltype (auto )
1646- format (const ::strong::formattable::modifier<type> & t, FormatContext& fc)
1647- noexcept (noexcept (std::declval<formatter<T, Char>>().format(value_of( std::declval<const type &>() ), fc)))
1641+ format (const Type & t, FormatContext& fc)
1642+ noexcept (noexcept (std::declval<formatter<T, Char>>().format(std::declval<const T &>(), fc)))
16481643 {
1649- const auto & tt = static_cast <const type&>(t);
1650- return formatter<T, Char>::format (value_of (tt), fc);
1644+ return formatter<T, Char>::format (value_of (t), fc);
16511645 }
16521646};
16531647#endif
16541648
16551649}
16561650
16571651#if STRONG_HAS_FMT_FORMAT
1658- namespace fmt
1659- {
1660- template <typename T, typename Tag, typename ... M, typename Char>
1661- struct formatter <::strong::type<T, Tag, M...>, Char>
1662- : std::enable_if_t <
1663- std::is_base_of<
1664- ::strong::formattable::modifier<
1665- ::strong::type<T, Tag, M...>
1666- >,
1667- ::strong::type<T, Tag, M...>
1668- >::value,
1669- formatter<T>
1670- >
1652+ namespace strong {
1653+
1654+ template <typename T, typename Char>
1655+ struct formatter ;
1656+
1657+ template <typename T, typename Tag, typename ... M, typename Char>
1658+ struct formatter <type<T, Tag, M...>, Char> : fmt::formatter<T, Char>
16711659{
1672- using type = ::strong::type<T, Tag, M...>;
1673- template <typename FormatContext>
1660+ template <typename FormatContext, typename Type>
16741661 STRONG_CONSTEXPR
16751662 decltype (auto )
1676- format (const ::strong::formattable::modifier<type> & t, FormatContext& fc)
1677- noexcept (noexcept (std::declval<formatter<T, Char>>().format(value_of( std::declval<const type &>() ), fc)))
1663+ format (const Type & t, FormatContext& fc)
1664+ noexcept (noexcept (std::declval<fmt:: formatter<T, Char>>().format(std::declval<const T &>(), fc)))
16781665 {
1679- const auto & tt = static_cast <const type&>(t);
1680- return formatter<T, Char>::format (value_of (tt), fc);
1666+ return fmt::formatter<T, Char>::format (value_of (t), fc);
16811667 }
16821668};
1669+
1670+ #if FMT_VERSION >= 90000
1671+
1672+ template <typename T, typename Char, bool = is_formattable<T>::value>
1673+ struct select_formatter ;
1674+
1675+ template <typename T, typename Char>
1676+ struct select_formatter <T, Char, true >
1677+ {
1678+ using type = formatter<T, Char>;
1679+ };
1680+
1681+ template <typename T, typename Char>
1682+ struct select_formatter <T, Char, false >
1683+ {
1684+ using type = fmt::ostream_formatter;
1685+ };
1686+
1687+ #endif
1688+ }
1689+ namespace fmt
1690+ {
1691+ #if FMT_VERSION >= 90000
1692+ template <typename T, typename Tag, typename ... M, typename Char>
1693+ struct formatter <::strong::type<T, Tag, M...>,
1694+ Char,
1695+ ::strong::impl::void_t <std::enable_if_t <::strong::is_ostreamable<::strong::type<T, Tag, M...>>::value ||
1696+ ::strong::is_formattable<::strong::type<T, Tag, M...>>::value>>>
1697+ : ::strong::select_formatter<::strong::type<T, Tag, M...>, Char>::type
1698+ {
1699+ };
1700+ #else
1701+ template <typename T, typename Tag, typename ... M, typename Char>
1702+ struct formatter <::strong::type<T, Tag, M...>,
1703+ Char,
1704+ ::strong::impl::void_t <std::enable_if_t <::strong::is_formattable<::strong::type<T, Tag, M...>>::value>>
1705+ >
1706+ : ::strong::formatter<::strong::type<T, Tag, M...>, Char>
1707+ {
1708+ };
1709+ #endif
1710+
16831711}
16841712#endif
16851713#endif // ROLLBEAR_STRONG_TYPE_HPP_INCLUDED
0 commit comments