Skip to content

Commit 13f1ccc

Browse files
committed
Revert "refactor(lib): polymorphic is value-type"
This reverts commit 479d1e7.
1 parent 755b91e commit 13f1ccc

File tree

2 files changed

+142
-499
lines changed

2 files changed

+142
-499
lines changed

include/mrdocs/ADT/Optional.hpp

Lines changed: 12 additions & 326 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include <mrdocs/Platform.hpp>
1717
#include <mrdocs/ADT/Nullable.hpp>
18-
#include <compare>
1918
#include <optional>
2019
#include <type_traits>
2120
#include <utility>
@@ -84,11 +83,6 @@ class Optional {
8483
}())
8584
{}
8685

87-
/** Construct from std::nullopt
88-
*/
89-
constexpr Optional(std::nullopt_t) noexcept(default_ctor_noex_())
90-
: Optional() {}
91-
9286
/// Copy constructor
9387
constexpr Optional(Optional const&) = default;
9488

@@ -108,18 +102,15 @@ class Optional {
108102
@param u The value to store. It must be convertible to T.
109103
**/
110104
template <class U>
111-
requires(
112-
!std::same_as<std::remove_cvref_t<U>, Optional>
113-
&& !std::same_as<std::remove_cvref_t<U>, std::in_place_t>
114-
&& !std::same_as<std::remove_cvref_t<U>, std::nullopt_t>
115-
&& std::is_constructible_v<T, U>)
105+
requires std::is_constructible_v<T, U>
116106
constexpr explicit Optional(U&& u) noexcept(
117107
std::is_nothrow_constructible_v<T, U>)
118108
: s_([&] {
119109
if constexpr (uses_nullable_traits)
120110
{
121111
return storage_t(static_cast<T>(std::forward<U>(u)));
122-
} else
112+
}
113+
else
123114
{
124115
return storage_t(std::forward<U>(u));
125116
}
@@ -131,20 +122,11 @@ class Optional {
131122
@param u The value to store. It must be convertible to T.
132123
**/
133124
template <class U>
134-
requires(
135-
!std::same_as<std::remove_cvref_t<U>, Optional>
136-
&& std::is_constructible_v<T, U> && std::is_assignable_v<T&, U>)
137-
constexpr
138-
Optional&
125+
requires std::is_constructible_v<T, U> && std::is_assignable_v<T&, U>
126+
constexpr Optional&
139127
operator=(U&& u) noexcept(std::is_nothrow_assignable_v<T&, U>)
140128
{
141-
if constexpr (uses_nullable_traits)
142-
{
143-
s_ = std::forward<U>(u);
144-
} else
145-
{
146-
s_ = std::forward<U>(u);
147-
}
129+
s_ = std::forward<U>(u);
148130
return *this;
149131
}
150132

@@ -348,311 +330,15 @@ class Optional {
348330
return *s_;
349331
}
350332
}
351-
};
352-
353-
namespace detail {
354-
template<typename T>
355-
inline constexpr bool isOptionalV = false;
356333

357-
template<typename T>
358-
inline constexpr bool isOptionalV<Optional<T>> = true;
359-
360-
template <typename T>
361-
using OptionalRelopT = std::enable_if_t<std::is_convertible_v<T, bool>, bool>;
362-
363-
template <typename T, typename U>
364-
using OptionalEqT = OptionalRelopT<
365-
decltype(std::declval<T const&>() == std::declval<U const&>())>;
366-
367-
template <typename T, typename U>
368-
using OptionalNeT = OptionalRelopT<
369-
decltype(std::declval<T const&>() != std::declval<U const&>())>;
370-
371-
template <typename T, typename U>
372-
using OptionalLtT = OptionalRelopT<
373-
decltype(std::declval<T const&>() < std::declval<U const&>())>;
374-
375-
template <typename T, typename U>
376-
using OptionalGtT = OptionalRelopT<
377-
decltype(std::declval<T const&>() > std::declval<U const&>())>;
378-
379-
template <typename T, typename U>
380-
using OptionalLeT = OptionalRelopT<
381-
decltype(std::declval<T const&>() <= std::declval<U const&>())>;
382-
383-
template <typename T, typename U>
384-
using OptionalGeT = detail::OptionalRelopT<
385-
decltype(std::declval<T const&>() >= std::declval<U const&>())>;
386-
387-
template <typename T>
388-
concept isDerivedFromOptional = requires(T const& __t) {
389-
[]<typename U>(Optional<U> const&) {
390-
}(__t);
334+
/** Three-way comparison defaults when supported by the underlying
335+
T/std::optional.
336+
**/
337+
auto
338+
operator<=>(Optional const&) const
339+
= default;
391340
};
392341

393-
} // namespace detail
394-
395-
/** Compares two Optional values for equality.
396-
397-
Returns true if both are engaged and their contained values are equal, or both are disengaged.
398-
*/
399-
template <typename T, typename U>
400-
constexpr detail::OptionalEqT<T, U>
401-
operator==(Optional<T> const& lhs, Optional<U> const& rhs)
402-
{
403-
return static_cast<bool>(lhs) == static_cast<bool>(rhs)
404-
&& (!lhs || *lhs == *rhs);
405-
}
406-
407-
/** Compares two Optional values for inequality.
408-
409-
Returns true if their engagement states differ or their contained values are not equal.
410-
*/
411-
template <typename T, typename U>
412-
constexpr detail::OptionalNeT<T, U>
413-
operator!=(Optional<T> const& lhs, Optional<U> const& rhs)
414-
{
415-
return static_cast<bool>(lhs) != static_cast<bool>(rhs)
416-
|| (static_cast<bool>(lhs) && *lhs != *rhs);
417-
}
418-
419-
/** Checks if the left Optional is less than the right Optional.
420-
421-
Returns true if the right is engaged and either the left is disengaged or its value is less.
422-
*/
423-
template <typename T, typename U>
424-
constexpr detail::OptionalLtT<T, U>
425-
operator<(Optional<T> const& lhs, Optional<U> const& rhs)
426-
{
427-
return static_cast<bool>(rhs) && (!lhs || *lhs < *rhs);
428-
}
429-
430-
/** Checks if the left Optional is greater than the right Optional.
431-
432-
Returns true if the left is engaged and either the right is disengaged or its value is greater.
433-
*/
434-
template <typename T, typename U>
435-
constexpr detail::OptionalGtT<T, U>
436-
operator>(Optional<T> const& lhs, Optional<U> const& rhs)
437-
{
438-
return static_cast<bool>(lhs) && (!rhs || *lhs > *rhs);
439-
}
440-
441-
/** Checks if the left Optional is less than or equal to the right Optional.
442-
443-
Returns true if the left is disengaged or the right is engaged and the left's value is less or equal.
444-
*/
445-
template <typename T, typename U>
446-
constexpr detail::OptionalLeT<T, U>
447-
operator<=(Optional<T> const& lhs, Optional<U> const& rhs)
448-
{
449-
return !lhs || (static_cast<bool>(rhs) && *lhs <= *rhs);
450-
}
451-
452-
/** Checks if the left Optional is greater than or equal to the right Optional.
453-
454-
Returns true if the right is disengaged or the left is engaged and its value is greater or equal.
455-
*/
456-
template <typename T, typename U>
457-
constexpr detail::OptionalGeT<T, U>
458-
operator>=(Optional<T> const& lhs, Optional<U> const& rhs)
459-
{
460-
return !rhs || (static_cast<bool>(lhs) && *lhs >= *rhs);
461-
}
462-
463-
/** Performs a three-way comparison between two Optional values.
464-
465-
If both are engaged, compares their contained values; otherwise, compares engagement state.
466-
*/
467-
template <typename T, std::three_way_comparable_with<T> U>
468-
[[nodiscard]]
469-
constexpr std::compare_three_way_result_t<T, U>
470-
operator<=>(Optional<T> const& x, Optional<U> const& y)
471-
{
472-
return x && y ? *x <=> *y : bool(x) <=> bool(y);
473-
}
474-
475-
/** Checks if the Optional is disengaged (equal to std::nullopt).
476-
477-
Returns true if the Optional does not contain a value.
478-
*/
479-
template <typename T>
480-
[[nodiscard]]
481-
constexpr bool
482-
operator==(Optional<T> const& lhs, std::nullopt_t) noexcept
483-
{
484-
return !lhs;
485-
}
486-
487-
/** Performs a three-way comparison between an Optional and std::nullopt.
488-
489-
Returns std::strong_ordering::greater if engaged, std::strong_ordering::equal if disengaged.
490-
*/
491-
template <typename T>
492-
[[nodiscard]]
493-
constexpr std::strong_ordering
494-
operator<=>(Optional<T> const& x, std::nullopt_t) noexcept
495-
{
496-
return bool(x) <=> false;
497-
}
498-
499-
/** Compares an engaged Optional to a value for equality.
500-
501-
Returns true if the Optional is engaged and its value equals rhs.
502-
*/
503-
template <typename T, typename U>
504-
requires(!detail::isOptionalV<U>)
505-
constexpr detail::OptionalEqT<T, U>
506-
operator== [[nodiscard]] (Optional<T> const& lhs, U const& rhs)
507-
{
508-
return lhs && *lhs == rhs;
509-
}
510-
511-
/** Compares a value to an engaged Optional for equality.
512-
513-
Returns true if the Optional is engaged and its value equals lhs.
514-
*/
515-
template <typename T, typename U>
516-
requires(!detail::isOptionalV<T>)
517-
constexpr detail::OptionalEqT<T, U>
518-
operator== [[nodiscard]] (T const& lhs, Optional<U> const& rhs)
519-
{
520-
return rhs && lhs == *rhs;
521-
}
522-
523-
/** Compares an Optional to a value for inequality.
524-
525-
Returns true if the Optional is disengaged or its value does not equal rhs.
526-
*/
527-
template <typename T, typename U>
528-
requires(!detail::isOptionalV<U>)
529-
constexpr detail::OptionalNeT<T, U>
530-
operator!= [[nodiscard]] (Optional<T> const& lhs, U const& rhs)
531-
{
532-
return !lhs || *lhs != rhs;
533-
}
534-
535-
/** Compares a value to an Optional for inequality.
536-
537-
Returns true if the Optional is disengaged or its value does not equal lhs.
538-
*/
539-
template <typename T, typename U>
540-
requires(!detail::isOptionalV<T>)
541-
constexpr detail::OptionalNeT<T, U>
542-
operator!= [[nodiscard]] (T const& lhs, Optional<U> const& rhs)
543-
{
544-
return !rhs || lhs != *rhs;
545-
}
546-
547-
/** Checks if the Optional is less than a value.
548-
549-
Returns true if the Optional is disengaged or its value is less than rhs.
550-
*/
551-
template <typename T, typename U>
552-
requires(!detail::isOptionalV<U>)
553-
constexpr detail::OptionalLtT<T, U>
554-
operator<[[nodiscard]] (Optional<T> const& lhs, U const& rhs)
555-
{
556-
return !lhs || *lhs < rhs;
557-
}
558-
559-
/** Checks if a value is less than an engaged Optional.
560-
561-
Returns true if the Optional is engaged and lhs is less than its value.
562-
*/
563-
template <typename T, typename U>
564-
requires(!detail::isOptionalV<T>)
565-
constexpr detail::OptionalLtT<T, U>
566-
operator<[[nodiscard]] (T const& lhs, Optional<U> const& rhs)
567-
{
568-
return rhs && lhs < *rhs;
569-
}
570-
571-
/** Checks if the Optional is greater than a value.
572-
573-
Returns true if the Optional is engaged and its value is greater than rhs.
574-
*/
575-
template <typename T, typename U>
576-
requires(!detail::isOptionalV<U>)
577-
constexpr detail::OptionalGtT<T, U>
578-
operator> [[nodiscard]] (Optional<T> const& lhs, U const& rhs)
579-
{
580-
return lhs && *lhs > rhs;
581-
}
582-
583-
/** Checks if a value is greater than an Optional.
584-
585-
Returns true if the Optional is disengaged or lhs is greater than its value.
586-
*/
587-
template <typename T, typename U>
588-
requires(!detail::isOptionalV<T>)
589-
constexpr detail::OptionalGtT<T, U>
590-
operator> [[nodiscard]] (T const& lhs, Optional<U> const& rhs)
591-
{
592-
return !rhs || lhs > *rhs;
593-
}
594-
595-
/** Checks if the Optional is less than or equal to a value.
596-
597-
Returns true if the Optional is disengaged or its value is less than or equal to rhs.
598-
*/
599-
template <typename T, typename U>
600-
requires(!detail::isOptionalV<U>)
601-
constexpr detail::OptionalLeT<T, U>
602-
operator<= [[nodiscard]] (Optional<T> const& lhs, U const& rhs)
603-
{
604-
return !lhs || *lhs <= rhs;
605-
}
606-
607-
/** Checks if a value is less than or equal to an engaged Optional.
608-
609-
Returns true if the Optional is engaged and lhs is less than or equal to its value.
610-
*/
611-
template <typename T, typename U>
612-
requires(!detail::isOptionalV<T>)
613-
constexpr detail::OptionalLeT<T, U>
614-
operator<= [[nodiscard]] (T const& lhs, Optional<U> const& rhs)
615-
{
616-
return rhs && lhs <= *rhs;
617-
}
618-
619-
/** Checks if the Optional is greater than or equal to a value.
620-
621-
Returns true if the Optional is engaged and its value is greater than or equal to rhs.
622-
*/
623-
template <typename T, typename U>
624-
requires(!detail::isOptionalV<U>)
625-
constexpr detail::OptionalGeT<T, U>
626-
operator>= [[nodiscard]] (Optional<T> const& lhs, U const& rhs)
627-
{
628-
return lhs && *lhs >= rhs;
629-
}
630-
631-
/** Checks if a value is greater than or equal to an Optional.
632-
633-
Returns true if the Optional is disengaged or lhs is greater than or equal to its value.
634-
*/
635-
template <typename T, typename U>
636-
requires(!detail::isOptionalV<T>)
637-
constexpr detail::OptionalGeT<T, U>
638-
operator>= [[nodiscard]] (T const& lhs, Optional<U> const& rhs)
639-
{
640-
return !rhs || lhs >= *rhs;
641-
}
642-
643-
/** Performs a three-way comparison between an Optional and a value.
644-
645-
If the Optional is engaged, compares its value to v; otherwise, returns less.
646-
*/
647-
template <typename T, typename U>
648-
requires(!detail::isDerivedFromOptional<U>)
649-
&& requires { typename std::compare_three_way_result_t<T, U>; }
650-
&& std::three_way_comparable_with<T, U>
651-
constexpr std::compare_three_way_result_t<T, U>
652-
operator<=> [[nodiscard]] (Optional<T> const& x, U const& v)
653-
{
654-
return bool(x) ? *x <=> v : std::strong_ordering::less;
655-
}
656342
} // namespace clang::mrdocs
657343

658344
#endif

0 commit comments

Comments
 (0)