Skip to content

Commit

Permalink
Containers: rework slicing APIs for more consistency.
Browse files Browse the repository at this point in the history
The bulk of work is mainly in how these are presented and documented,
with just two of them being deprecated in favor of better-named
variants:

 - except() is now exceptSuffix(), since that's how I named the new
   StringView API that removes a string suffix, and it just makes much
   more sense that way. Too bad it took me so long to realize a good
   name.
 - As a consequence, suffix() is now exceptPrefix(), again consistent
   with the StringView API, because both take a prefix length and not
   suffix length. This means, once enough time passes (say, a year after
   a release the deprecated API gets removed, and then again a year), it
   can be reintroduced taking a *suffix* length, since that's what it
   should have been since the beginning. But again, I realized the
   inconsistency way too late.

To ensure nothing is broken, existing code is not adapted to these
changes -- only a new test is added for a new suffix<count>() which
could be added without clashes. Adapting the code will be done in the
next commit.
  • Loading branch information
mosra committed Mar 9, 2022
1 parent 62e48bd commit c6f3ec5
Show file tree
Hide file tree
Showing 11 changed files with 741 additions and 278 deletions.
18 changes: 17 additions & 1 deletion doc/corrade-changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,22 @@ namespace Corrade {
other APIs returning a @cpp bool @ce as well as the new
@ref Containers::String and @ref Containers::BasicStringView "StringView"
APIs, which all use `isSomething()` instead.
- @ref Containers::Array, @relativeref{Containers,ArrayView},
@relativeref{Containers,StaticArray},
@relativeref{Containers,StaticArrayView} and
@relativeref{Containers,StridedArrayView} slicing APIs were reworked for
more consistency. In particular:
- @cpp except() @ce is deprecated in favor of
@relativeref{Containers::ArrayView,exceptSuffix()}, being consistent
with the new @ref Containers::StringView::exceptSuffix(StringView) const
API
- @cpp suffix() @ce is deprecated in favor of
@relativeref{Containers::ArrayView,exceptPrefix()}, being consistent
with the new @ref Containers::StringView::exceptPrefix(StringView) const
API, as both take a prefix length, and not suffix length. The
@cpp suffix() @ce API, taking a suffix length instead of an offset, is
scheduled to be reintroduced once enough time passes after the
deprecated API gets removed to avoid silent breakages in existing code.
- @cpp Utility::Directory::isSandboxed() @ce is deprecated in favor of
@ref Utility::System::isSandboxed(), as that's the better place for this
API to live in
Expand Down Expand Up @@ -851,7 +867,7 @@ Released 2019-10-24, tagged as
@ref Containers::Array::slice() const and @ref Containers::StaticArray::slice() const variants that take both being and
end offsets at compile time (and thus also more range checking at compile
time)
- Added @ref Containers::ArrayView::except() and similar APIs to
- Added @cpp Containers::ArrayView::except() @ce and similar APIs to
@ref Containers::StaticArrayView, @ref Containers::Array,
@ref Containers::StaticArray and @ref Containers::StridedArrayView. It's
like @ref Containers::ArrayView::prefix() but taking a count of items to
Expand Down
9 changes: 5 additions & 4 deletions doc/snippets/Containers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,12 @@ if(view.size() > 2 && view[2] < 3) view[2] += 5;
int data[]{0, 10, 20, 30, 40, 50, 60};
Containers::ArrayView<int> view = data;

Containers::ArrayView<int> a = view.slice(3, 5); // {30, 40, 50}
Containers::ArrayView<int> b = view.prefix(4); // {0, 10, 20, 30}
Containers::ArrayView<int> c = view.suffix(2); // {50, 60}
Containers::ArrayView<int> d = view.except(2); // {0, 10, 20, 30, 40}
Containers::ArrayView<int> a = view.slice(3, 5); // {30, 40, 50}
Containers::ArrayView<int> b = view.prefix(4); // {0, 10, 20, 30}
Containers::ArrayView<int> c = view.exceptPrefix(4); // {40, 50, 60}
Containers::ArrayView<int> d = view.exceptSuffix(2); // {0, 10, 20, 30, 40}
/* [ArrayView-usage-slicing] */
/** @todo add suffix(2) above once it actually takes two last items */
static_cast<void>(a);
static_cast<void>(b);
static_cast<void>(c);
Expand Down
159 changes: 116 additions & 43 deletions src/Corrade/Containers/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ class Array {
const T& back() const; /**< @overload */

/**
* @brief Array slice
* @brief View on a slice
*
* Equivalent to @ref ArrayView::slice(T*, T*) const and overloads.
*/
Expand All @@ -588,28 +588,28 @@ class Array {
}

/**
* @brief Fixed-size array slice
* @brief Fixed-size view on a slice
*
* Equivalent to @ref ArrayView::slice(T*) const and overloads.
*/
template<std::size_t size> StaticArrayView<size, T> slice(T* begin) {
return ArrayView<T>(*this).template slice<size>(begin);
template<std::size_t count> StaticArrayView<count, T> slice(T* begin) {
return ArrayView<T>(*this).template slice<count>(begin);
}
/** @overload */
template<std::size_t size> StaticArrayView<size, const T> slice(const T* begin) const {
return ArrayView<const T>(*this).template slice<size>(begin);
template<std::size_t count> StaticArrayView<count, const T> slice(const T* begin) const {
return ArrayView<const T>(*this).template slice<count>(begin);
}
/** @overload */
template<std::size_t size> StaticArrayView<size, T> slice(std::size_t begin) {
return ArrayView<T>(*this).template slice<size>(begin);
template<std::size_t count> StaticArrayView<count, T> slice(std::size_t begin) {
return ArrayView<T>(*this).template slice<count>(begin);
}
/** @overload */
template<std::size_t size> StaticArrayView<size, const T> slice(std::size_t begin) const {
return ArrayView<const T>(*this).template slice<size>(begin);
template<std::size_t count> StaticArrayView<count, const T> slice(std::size_t begin) const {
return ArrayView<const T>(*this).template slice<count>(begin);
}

/**
* @brief Fixed-size array slice
* @brief Fixed-size view on a slice
* @m_since{2019,10}
*
* Equivalent to @ref ArrayView::slice() const.
Expand All @@ -627,9 +627,9 @@ class Array {
}

/**
* @brief Array prefix
* @brief View on a prefix until a pointer
*
* Equivalent to @ref ArrayView::prefix(T*) const and overloads.
* Equivalent to @ref ArrayView::prefix(T*) const.
*/
ArrayView<T> prefix(T* end) {
return ArrayView<T>(*this).prefix(end);
Expand All @@ -638,61 +638,134 @@ class Array {
ArrayView<const T> prefix(const T* end) const {
return ArrayView<const T>(*this).prefix(end);
}
/** @overload */
ArrayView<T> prefix(std::size_t end) {
return ArrayView<T>(*this).prefix(end);

/**
* @brief View on a suffix after a pointer
*
* Equivalent to @ref ArrayView::suffix(T*) const.
*/
ArrayView<T> suffix(T* begin) {
return ArrayView<T>(*this).suffix(begin);
}
/** @overload */
ArrayView<const T> prefix(std::size_t end) const {
return ArrayView<const T>(*this).prefix(end);
ArrayView<const T> suffix(const T* begin) const {
return ArrayView<const T>(*this).suffix(begin);
}

/** @overload */
template<std::size_t viewSize> StaticArrayView<viewSize, T> prefix() {
return ArrayView<T>(*this).template prefix<viewSize>();
/**
* @brief View on the first @p count items
*
* Equivalent to @ref ArrayView::prefix(std::size_t) const.
*/
ArrayView<T> prefix(std::size_t count) {
return ArrayView<T>(*this).prefix(count);
}
/** @overload */
template<std::size_t viewSize> StaticArrayView<viewSize, const T> prefix() const {
return ArrayView<const T>(*this).template prefix<viewSize>();
ArrayView<const T> prefix(std::size_t count) const {
return ArrayView<const T>(*this).prefix(count);
}

/* Here will be suffix(std::size_t count), view on the last count
items, once the deprecated suffix(std::size_t begin) is gone and
enough time passes to not cause silent breakages in existing code.
The fixed-size suffix<count>() below could be added already as it
doesn't clash with anything. */

/**
* @brief Array suffix
* @brief Fixed-size view on the first @p count items
*
* Equivalent to @ref ArrayView::suffix(T*) const and overloads.
* Equivalent to @ref ArrayView::prefix() const.
*/
ArrayView<T> suffix(T* begin) {
return ArrayView<T>(*this).suffix(begin);
template<std::size_t count> StaticArrayView<count, T> prefix() {
return ArrayView<T>(*this).template prefix<count>();
}
/** @overload */
ArrayView<const T> suffix(const T* begin) const {
return ArrayView<const T>(*this).suffix(begin);
template<std::size_t count> StaticArrayView<count, const T> prefix() const {
return ArrayView<const T>(*this).template prefix<count>();
}
/** @overload */
ArrayView<T> suffix(std::size_t begin) {
return ArrayView<T>(*this).suffix(begin);

/**
* @brief Fixed-size view on the last @p count items
* @m_since_latest
*
* Equivalent to @ref ArrayView::suffix() const.
*/
template<std::size_t count> StaticArrayView<count, T> suffix() {
return ArrayView<T>(*this).template suffix<count>();
}
/** @overload */
ArrayView<const T> suffix(std::size_t begin) const {
return ArrayView<const T>(*this).suffix(begin);
/**
* @overload
* @m_since_latest
*/
template<std::size_t count> StaticArrayView<count, const T> suffix() const {
return ArrayView<const T>(*this).template suffix<count>();
}

/**
* @brief Array prefix except the last @p count items
* @m_since{2019,10}
* @brief View except the first @p count items
* @m_since_latest
*
* Equivalent to @ref ArrayView::except().
* Equivalent to @ref ArrayView::exceptPrefix(std::size_t) const.
*/
ArrayView<T> except(std::size_t count) {
return ArrayView<T>(*this).except(count);
ArrayView<T> exceptPrefix(std::size_t count) {
return ArrayView<T>(*this).exceptPrefix(count);
}
/**
* @overload
* @m_since{2019,10}
* @m_since_latest
*/
ArrayView<const T> exceptPrefix(std::size_t count) const {
return ArrayView<const T>(*this).exceptPrefix(count);
}

#ifdef CORRADE_BUILD_DEPRECATED
/** @copybrief exceptPrefix()
* @m_deprecated_since_latest Use @ref exceptPrefix() instead.
*/
CORRADE_DEPRECATED("use exceptPrefix() instead") ArrayView<T> suffix(std::size_t begin) {
return ArrayView<T>(*this).exceptPrefix(begin);
}
/** @copybrief exceptPrefix()
* @m_deprecated_since_latest Use @ref exceptPrefix() instead.
*/
CORRADE_DEPRECATED("use exceptPrefix() instead") ArrayView<const T> suffix(std::size_t begin) const {
return ArrayView<const T>(*this).exceptPrefix(begin);
}
#endif

/**
* @brief View except the last @p count items
* @m_since_latest
*
* Equivalent to @ref ArrayView::exceptSuffix().
*/
ArrayView<T> exceptSuffix(std::size_t count) {
return ArrayView<T>(*this).exceptSuffix(count);
}
/**
* @overload
* @m_since_latest
*/
ArrayView<const T> exceptSuffix(std::size_t count) const {
return ArrayView<const T>(*this).exceptSuffix(count);
}

#ifdef CORRADE_BUILD_DEPRECATED
/**
* @copybrief exceptSuffix()
* @m_deprecated_since_latest Use @ref exceptSuffix() instead.
*/
CORRADE_DEPRECATED("use exceptSuffix() instead") ArrayView<T> except(std::size_t count) {
return ArrayView<T>(*this).exceptSuffix(count);
}
/**
* @overload
* @m_deprecated_since_latest Use @ref exceptSuffix() instead.
*/
ArrayView<const T> except(std::size_t count) const {
return ArrayView<const T>(*this).except(count);
CORRADE_DEPRECATED("use exceptSuffix() instead") ArrayView<const T> except(std::size_t count) const {
return ArrayView<const T>(*this).exceptSuffix(count);
}
#endif

/**
* @brief Release data storage
Expand Down
Loading

0 comments on commit c6f3ec5

Please sign in to comment.