gobo-eiffel / gobo

The Gobo Eiffel Project provides the Eiffel community with free and portable Eiffel tools and libraries.
https://sourceforge.net/projects/gobo-eiffel/
Other
59 stars 24 forks source link

DS_ARRAYED_LIST: valid_index #41

Closed phgachoud closed 4 years ago

phgachoud commented 4 years ago

Ran into an issue with valid_index precondition using a DS_ARRAYED_LIST. It seems that the valid_index in inherited from DS_LIST and not implemented again. So my question has 2 wings:

  1. Is there a reason not to add a valid_index precondition to at alias "@", item (i: INTEGER): G
  2. Is there any reason not to implement

FROM DS_LIST

    valid_index (i: INTEGER): BOOLEAN
        -- Is `i' a valid index value?
    do
        Result := 0 <= i and i <= (count + 1)
    ensure
        definition: Result = (0 <= i and i <= (count + 1))
    end

SUGGESTED

inherit
        DS_LIST
            redefine
                valid_index
            end

    valid_index (i: INTEGER): BOOLEAN
            -- Is `i' a valid index value?
        do
            Result := storage.valid_index (i)
        ensure
            definition: storage.valid_index (i)
        end

at alias "@", item (i: INTEGER): G
        -- Item at index `i'
        -- (Performance: O(1).)
            require
                    valid_index: storage.valid_index (i - 1)
    do
        Result := storage.item (i - 1)
    end

I use it with content: DS_ARRAYED_LIST. content.valid_index(0) returns True as it shouldn't

Screenshot_20191125_082550

ebezault commented 4 years ago

In lists the cursor can be before (index = 0) or after (index = count + 1). This is true for arrayed list as well (which is a list). So in this context, a valid index does not mean that there is a item available at that cursor position. That's why feature item does not use valid_index in its precondition. An arrayed list is not an array, it's a list. So valid_index is about the list cursor, not about availability of items in an array. The precondition of item comes from DS_INDEXABLE, where there is no notion of before or after. Perhaps what is missing is a valid_index routine in DS_INDEXABLE. But it is not the same valid_index as in DS_LIST. So in DS_ARRAYED_LIST there should be two different routines: valid_item_index (from DS_INDEXABLE.valid_index) and valid_cursor_index (from DS_LIST.valid_index). But for backward compatibility we have to keep valid_index in DS_ARRAYED_LIST with the implementation of DS_LIST.

phgachoud commented 4 years ago

Thx for your explanation of the implementation and implications, I'd have to say that I still miss some function to check if I can call item with a particular index. So my workaround is

        if content.valid_index (a_col_index) and a_col_index >= 1 and a_col_index <= count then
            Result := content.item (a_col_index)
                    end

Don't know if you want me to close the issue.

ebezault commented 4 years ago

The following code should be enough, as per the precondition:

        if a_col_index >= 1 and a_col_index <= a_list.count then
            Result := a_list.item (a_col_index)
                end
phgachoud commented 4 years ago

The following code should be enough, as per the precondition:

      if a_col_index >= 1 and a_col_index <= a_list.count then
          Result := a_list.item (a_col_index)
                end

Closing the issue, could be an improvment