diff --git a/examples/03_conversions.cpp b/examples/03_conversions.cpp index 766b9f3..4a849b4 100644 --- a/examples/03_conversions.cpp +++ b/examples/03_conversions.cpp @@ -34,7 +34,7 @@ void pointer_conversions() tcb::pointer p3 = tcb::const_pointer_cast(p2); // Similarly, we can implicitly convert from a pointer-to-derived - // to a pointer-to-base, as we'd expect: + // to an unambiguous pointer-to-base, as we'd expect: Derived d{}; tcb::pointer p_base = tcb::ptr_to_mut(d); diff --git a/include/tcb/pointer.hpp b/include/tcb/pointer.hpp index 76e8043..ad6cafa 100644 --- a/include/tcb/pointer.hpp +++ b/include/tcb/pointer.hpp @@ -168,7 +168,7 @@ struct TCB_PTR_GSL_POINTER(T) pointer { friend constexpr auto operator==(pointer lhs, pointer rhs) -> bool { - return lhs.addr_ == rhs.addr_; + return std::compare_three_way{}(lhs.addr_, rhs.addr_) == 0; } friend constexpr auto operator<=>(pointer lhs, pointer rhs) -> std::strong_ordering @@ -413,13 +413,15 @@ struct TCB_PTR_GSL_POINTER(T) checked_iterator { return lhs -= rhs; } - friend constexpr auto operator-(checked_iterator lhs, checked_iterator rhs) -> difference_type + friend constexpr auto operator-(checked_iterator const& lhs, checked_iterator const& rhs) + -> difference_type { return lhs.pos_ - rhs.pos_; } - friend auto operator==(checked_iterator, checked_iterator) -> bool = default; - friend auto operator<=>(checked_iterator, checked_iterator) -> std::strong_ordering = default; + friend auto operator==(checked_iterator const&, checked_iterator const&) -> bool = default; + friend auto operator<=>(checked_iterator const&, checked_iterator const&) + -> std::strong_ordering = default; }; #ifndef TCB_PTR_USE_UNCHECKED_ITERATORS @@ -468,6 +470,9 @@ struct TCB_PTR_GSL_POINTER(T) slice { constexpr explicit slice(T* addr, std::size_t sz) : addr_(addr), sz_(sz) { } + slice(slice const&) = default; + auto operator=(slice const&) -> slice& = default; + public: using value_type = T; using size_type = std::size_t; @@ -481,9 +486,6 @@ struct TCB_PTR_GSL_POINTER(T) slice { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - slice(slice const&) = delete; - void operator=(slice const&) = delete; - constexpr auto operator[](size_type idx) -> reference { if (idx >= sz_) { @@ -655,9 +657,7 @@ struct TCB_PTR_GSL_POINTER(T) pointer { return pointer(ptr, sz); } - constexpr pointer(pointer const& other) noexcept : slice_(other.slice_.addr_, other.slice_.sz_) - { - } + pointer(pointer const&) = default; // If we are const, allow copy-construction from non-const constexpr pointer(pointer[]> const& other) noexcept @@ -666,12 +666,7 @@ struct TCB_PTR_GSL_POINTER(T) pointer { { } - constexpr auto operator=(pointer const& other) noexcept -> pointer& - { - slice_.addr_ = other.slice_.addr_; - slice_.sz_ = other.slice_.sz_; - return *this; - } + auto operator=(pointer const&) -> pointer& = default; constexpr auto operator*() const& noexcept TCB_PTR_LIFETIME_BOUND->element_type& { diff --git a/tests/pointer.test.cpp b/tests/pointer.test.cpp index bb42387..c0bebc0 100755 --- a/tests/pointer.test.cpp +++ b/tests/pointer.test.cpp @@ -143,14 +143,11 @@ constexpr bool test_pointer_static_properties() static_assert(std::swappable

); // pointer special members are all trivial - // (except array pointers, annoyingly) - if constexpr (not std::is_unbounded_array_v) { - static_assert(std::is_trivially_copyable_v

); - static_assert(std::is_trivially_copy_constructible_v

); - static_assert(std::is_trivially_move_constructible_v

); - static_assert(std::is_trivially_copy_assignable_v

); - static_assert(std::is_trivially_move_assignable_v

); - } + static_assert(std::is_trivially_copyable_v

); + static_assert(std::is_trivially_copy_constructible_v

); + static_assert(std::is_trivially_move_constructible_v

); + static_assert(std::is_trivially_copy_assignable_v

); + static_assert(std::is_trivially_move_assignable_v

); static_assert(std::is_trivially_destructible_v

); // pointer special members are all noexcept @@ -1335,7 +1332,7 @@ constexpr bool test_std_optional_specialisation() static_assert(std::default_initializable); static_assert(std::copy_constructible); static_assert(std::move_constructible); - // static_assert(std::copyable); + static_assert(std::copyable); static_assert(std::movable); static_assert(std::destructible); }