diff --git a/include/gsl/dyn_array b/include/gsl/dyn_array index b59cc25..a54bd1d 100644 --- a/include/gsl/dyn_array +++ b/include/gsl/dyn_array @@ -34,6 +34,9 @@ namespace gsl { +template > +class dyn_array; + namespace details { template > @@ -178,13 +181,6 @@ namespace details constexpr dyn_array_iterator() = default; #endif /* __cpp_lib_ranges >= 201911L */ - constexpr dyn_array_iterator(pointer ptr, size_type pos, size_type end_pos) - : _ptr{ptr}, _pos{pos}, _end_pos{end_pos} - { - Ensures((_ptr != nullptr && _end_pos > 0) || (_ptr == nullptr && _end_pos == 0)); - Ensures(_pos <= _end_pos); - } - constexpr operator dyn_array_iterator() const { return {_ptr, _pos, _end_pos}; } #if defined(_MSC_VER) && defined(__cpp_lib_ranges) && (__cpp_lib_ranges >= 201911L) @@ -281,13 +277,23 @@ namespace details } private: + constexpr dyn_array_iterator(pointer ptr, size_type pos, size_type end_pos) + : _ptr{ptr}, _pos{pos}, _end_pos{end_pos} + { + Ensures((_ptr != nullptr && _end_pos > 0) || (_ptr == nullptr && _end_pos == 0)); + Ensures(_pos <= _end_pos); + } + pointer _ptr{}; size_type _pos{}; size_type _end_pos{}; + + template + friend class ::gsl::dyn_array; }; } // namespace details -template > +template class dyn_array : private details::dyn_array_base { using base = details::dyn_array_base; diff --git a/include/gsl/span b/include/gsl/span index e7117a1..090a8bd 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -139,12 +139,6 @@ namespace details #endif // _MSC_VER constexpr span_iterator() = default; - constexpr span_iterator(pointer begin, pointer end, pointer current) - : begin_(begin), end_(end), current_(current) - { - Expects(begin_ <= current_ && current <= end_); - } - constexpr operator span_iterator() const noexcept { return {begin_, end_, current_}; @@ -335,10 +329,21 @@ namespace details } #endif + private: + constexpr span_iterator(pointer begin, pointer end, pointer current) + : begin_(begin), end_(end), current_(current) + { + Expects(begin_ <= current_ && current <= end_); + } + pointer begin_ = nullptr; pointer end_ = nullptr; pointer current_ = nullptr; + template + friend class span_iterator; + template + friend class ::gsl::span; template friend struct std::pointer_traits; }; diff --git a/tests/dyn_array_tests.cpp b/tests/dyn_array_tests.cpp index 7f19d18..46efc63 100644 --- a/tests/dyn_array_tests.cpp +++ b/tests/dyn_array_tests.cpp @@ -19,6 +19,20 @@ static_assert(sizeof(gsl::dyn_array) == 2 * sizeof(void*), static_assert( std::is_convertible::iterator, gsl::dyn_array::const_iterator>::value, "gsl::dyn_array iterator should be implicitly convertible to const_iterator"); +static_assert(!std::is_constructible::iterator, gsl::dyn_array&>::value, + "dyn_array::iterator should not be constructible from dyn_array"); +static_assert( + !std::is_constructible::iterator, int*, std::size_t, std::size_t>::value, + "dyn_array::iterator should not be constructible from an arbitrary state triple"); +static_assert( + !std::is_constructible::const_iterator, const gsl::dyn_array&>::value, + "dyn_array::const_iterator should not be constructible from dyn_array"); +static_assert(!std::is_constructible::const_iterator, const int*, std::size_t, + std::size_t>::value, + "dyn_array::const_iterator should not be constructible from an arbitrary state " + "triple"); +static_assert(std::is_copy_constructible::iterator>::value, + "dyn_array::iterator should remain copy constructible"); #if defined(__cpp_lib_concepts) && (__cpp_lib_concepts >= 202002L) static_assert(std::input_iterator::iterator>, diff --git a/tests/span_compatibility_tests.cpp b/tests/span_compatibility_tests.cpp index 922cdfe..e69e0aa 100644 --- a/tests/span_compatibility_tests.cpp +++ b/tests/span_compatibility_tests.cpp @@ -654,6 +654,19 @@ static_assert(std::is_trivially_copyable>::value, static_assert(std::is_trivially_copyable::iterator>::value, "span::iterator should be trivially copyable"); +static_assert(!std::is_constructible::iterator, gsl::span>::value, + "span::iterator should not be constructible from span"); +static_assert(!std::is_constructible::iterator, int*, int*, int*>::value, + "span::iterator should not be constructible from an arbitrary pointer triple"); +static_assert(!std::is_constructible::iterator, gsl::span>::value, + "span::iterator should not be constructible from span"); +static_assert( + !std::is_constructible::iterator, const int*, const int*, + const int*>::value, + "span::iterator should not be constructible from an arbitrary pointer triple"); +static_assert(std::is_copy_constructible::iterator>::value, + "span::iterator should remain copy constructible"); + // nothrow constructible assertions static_assert(std::is_nothrow_constructible, int*, std::size_t>::value, "std::is_nothrow_constructible, int*, std::size_t>");