@@ -120,7 +120,8 @@ namespace impl {
120120template <typename Cmp = std::less<>, typename ForwardIt, typename E>
121121constexpr ForwardIt lower_bound (ForwardIt first, ForwardIt last, E&& e, Cmp&& comp = {}) {
122122 auto count = std::distance (first, last);
123- for (auto it = first; count > 0 ;) {
123+ while (count > 0 ) {
124+ auto it = first;
124125 auto step = count / 2 ;
125126 std::advance (it, step);
126127 if (comp (*it, e)) {
@@ -235,27 +236,33 @@ struct name_sort_impl<void, Cmp> {
235236 [[nodiscard]] constexpr bool operator ()(string_view s1, string_view s2) const noexcept { return lexicographical_compare<C>(s1, s2); }
236237 };
237238
239+ template <typename T>
240+ using cmp_arg_t = std::conditional_t <std::is_enum_v<std::decay_t <T>> || std::is_constructible_v<string_view, T>, string_view, T>;
241+
242+ template <typename T>
243+ [[nodiscard]] static constexpr decltype (auto ) cmp_arg(T&& value) noexcept {
244+ using D = std::decay_t <T>;
245+ if constexpr (std::is_enum_v<D>) {
246+ return enum_name (value);
247+ } else if constexpr (std::is_constructible_v<string_view, T>) {
248+ return string_view{std::forward<T>(value)};
249+ } else {
250+ return std::forward<T>(value);
251+ }
252+ }
253+
238254 template <typename E1 , typename E2 >
239255 [[nodiscard]] constexpr std::enable_if_t <
240256 // at least one of need to be an enum type
241257 (std::is_enum_v<std::decay_t <E1 >> || std::is_enum_v<std::decay_t <E2 >>) &&
242258 // if both is enum, only accept if the same enum
243259 (!std::is_enum_v<std::decay_t <E1 >> || !std::is_enum_v<std::decay_t <E2 >> || std::is_same_v<E1 , E2 >) &&
244260 // is invocable with comparator
245- (std::is_invocable_r_v<bool , FullCmp<>, std:: conditional_t <std::is_enum_v<std:: decay_t < E1 >>, string_view, E1 >, std:: conditional_t <std::is_enum_v<std:: decay_t < E2 >>, string_view, E2 >>),
261+ (std::is_invocable_r_v<bool , FullCmp<>, cmp_arg_t < E1 >, cmp_arg_t < E2 >>),
246262 bool >
247263 operator ()(E1 e1 , E2 e2 ) const noexcept {
248- using D1 = std::decay_t <E1 >;
249- using D2 = std::decay_t <E2 >;
250264 constexpr FullCmp<> cmp{};
251-
252- if constexpr (std::is_enum_v<D1 > && std::is_enum_v<D2 >) {
253- return cmp (enum_name (e1 ), enum_name (e2 ));
254- } else if constexpr (std::is_enum_v<D1 >) {
255- return cmp (enum_name (e1 ), e2 );
256- } else /* if constexpr (std::is_enum_v<D2>) */ {
257- return cmp (e1 , enum_name (e2 ));
258- }
265+ return cmp (cmp_arg (e1 ), cmp_arg (e2 ));
259266 }
260267};
261268
@@ -675,7 +682,7 @@ class bitset {
675682 [[nodiscard]] static constexpr iterator_impl end (parent_t p) noexcept {
676683 return iterator_impl (p, enum_count<E>());
677684 }
678-
685+
679686 public:
680687 [[nodiscard]] constexpr reference operator *() const noexcept { return *Index::it (num_index * bits_per_base + static_cast <std::size_t >(detail::countr_zero (bit_index))); }
681688
@@ -774,7 +781,7 @@ class bitset {
774781 }
775782
776783 constexpr explicit bitset (detail::raw_access_t , const char_type* str, std::size_t n = ~std::size_t {0 }, char_type zero = static_cast <char_type>(' 0' ), char_type one = static_cast<char_type>(' 1' ))
777- : bitset(string_view{str, (std::min)(std::char_traits<char_type>::length (str), n)}, 0 , n, zero, one) {}
784+ : bitset(detail:: raw_access_t {}, string_view{str, (std::min)(std::char_traits<char_type>::length (str), n)}, 0 , n, zero, one) {}
778785
779786 constexpr bitset (std::initializer_list<E> starters) : a{{}} {
780787 if constexpr (magic_enum::detail::subtype_v<E> == magic_enum::detail::enum_subtype::flags) {
0 commit comments