|
|
@@ -45,29 +45,49 @@ struct non_movable_mixin: Type {
|
|
|
non_movable_mixin &operator=(const non_movable_mixin &) noexcept = default;
|
|
|
};
|
|
|
|
|
|
-struct empty_mixin {};
|
|
|
+struct empty_type {};
|
|
|
|
|
|
+struct aggregate_type {
|
|
|
+ [[nodiscard]] constexpr bool operator==(const aggregate_type &) const noexcept = default;
|
|
|
+ [[nodiscard]] constexpr auto operator<=>(const aggregate_type &) const noexcept = default;
|
|
|
+ int value{};
|
|
|
+};
|
|
|
+
|
|
|
+template<typename Type>
|
|
|
struct value_type {
|
|
|
constexpr value_type() = default;
|
|
|
- constexpr value_type(int elem): value{elem} {}
|
|
|
+ constexpr value_type(Type elem): value{elem} {}
|
|
|
[[nodiscard]] constexpr bool operator==(const value_type &) const noexcept = default;
|
|
|
[[nodiscard]] constexpr auto operator<=>(const value_type &) const noexcept = default;
|
|
|
- int value{};
|
|
|
+ operator Type() const noexcept {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ Type value{};
|
|
|
};
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
|
-using pointer_stable = internal::pointer_stable_mixin<internal::value_type>;
|
|
|
-using non_default_constructible = internal::non_default_constructible_mixin<internal::value_type>;
|
|
|
-using non_trivially_destructible = internal::non_trivially_destructible_mixin<internal::value_type>;
|
|
|
-using pointer_stable_non_trivially_destructible = internal::pointer_stable_mixin<internal::non_trivially_destructible_mixin<internal::value_type>>;
|
|
|
-using non_comparable = internal::non_comparable_mixin<internal::empty_mixin>;
|
|
|
-using non_movable = internal::non_movable_mixin<internal::value_type>;
|
|
|
-
|
|
|
-static_assert(std::is_trivially_destructible_v<test::pointer_stable>, "Not a trivially destructible type");
|
|
|
-static_assert(!std::is_trivially_destructible_v<test::non_trivially_destructible>, "Trivially destructible type");
|
|
|
-static_assert(!std::is_trivially_destructible_v<test::pointer_stable_non_trivially_destructible>, "Trivially destructible type");
|
|
|
-static_assert(!std::is_move_constructible_v<test::non_movable> && !std::is_move_assignable_v<test::non_movable>, "Movable type");
|
|
|
+using pointer_stable = internal::pointer_stable_mixin<internal::value_type<int>>;
|
|
|
+using pointer_stable_non_trivially_destructible = internal::pointer_stable_mixin<internal::non_trivially_destructible_mixin<internal::value_type<int>>>;
|
|
|
+
|
|
|
+using non_default_constructible = internal::non_default_constructible_mixin<internal::value_type<int>>;
|
|
|
+using non_trivially_destructible = internal::non_trivially_destructible_mixin<internal::value_type<int>>;
|
|
|
+using non_comparable = internal::non_comparable_mixin<internal::empty_type>;
|
|
|
+using non_movable = internal::non_movable_mixin<internal::value_type<int>>;
|
|
|
+
|
|
|
+using boxed_int = internal::value_type<int>;
|
|
|
+using boxed_char = internal::value_type<char>;
|
|
|
+
|
|
|
+using empty = internal::empty_type;
|
|
|
+struct other_empty: internal::empty_type {};
|
|
|
+
|
|
|
+using aggregate = internal::aggregate_type;
|
|
|
+
|
|
|
+static_assert(std::is_trivially_destructible_v<pointer_stable>, "Not a trivially destructible type");
|
|
|
+static_assert(!std::is_trivially_destructible_v<non_trivially_destructible>, "Trivially destructible type");
|
|
|
+static_assert(!std::is_trivially_destructible_v<pointer_stable_non_trivially_destructible>, "Trivially destructible type");
|
|
|
+static_assert(!std::is_move_constructible_v<non_movable> && !std::is_move_assignable_v<non_movable>, "Movable type");
|
|
|
+static_assert(std::is_aggregate_v<aggregate>, "Not an aggregate type");
|
|
|
|
|
|
} // namespace test
|
|
|
|