Feature Request - looping through properties

it would be really useful when the foreach would not enter NOTFOUND lists.

Currently with every list I receive from get_property I need to check if the property is set. If a property is not set <var>-NOTFOUND is received, which requires additional error handling when looping through the list.

foreach( x in LISTS mylist )
    message( "x = ${x}" )
endforeach()

This sounds like a use case for a list(FILTER mylist PREDICATE "item") (where item is the variable available to the predicate and would be evaluated as if (${predicate_arg})) to be added.

I don’t think we can change foreach to do this silently without a policy that would fire on just about every foreach (IN LISTS) usage today.

1 Like

It looks like a good idea to me! (the PREDICATE named keyword).
IMHO the better way is to have smth even more generic like this:

function(my_predicate result_var item)
    if(<check `item` somehow>)
        set(${result_var} TRUE PARENT_SCOPE)
    else()
        set(${result_var} FALSE PARENT_SCOPE)
    endif()
endfunction()

list(FILTER list_var PREDICATE [[my_predicate(${result} ${item})]])

For every item the list(...PREDICATE...) gonna substitute the item placeholder w/ the current value and the result w/ a temporary result variable name and evaluate the CMake code…

This way allows to write any custom predicate with much more complex logic than just whatever if allows or to have partial application for arguments. Example:

function(less_than first second result_var)
    if(first LESS second)
        set(${result_var} TRUE PARENT_SCOPE)
    else()
        set(${result_var} FALSE PARENT_SCOPE)
    endif()
endfunction()

list(APPEND numbers 1 2 3 4 5 6)
list(FILTER numbers PREDICATE [[less_than(${item} 3 ${result})]])

The other candidate for PREDICATE-like logic is the list(TRANSFORM).
Recently, while debugging my CPack install script I wanted to print all available variables… IMHO, it’ll be nice to be able to write smth like this:

get_cmake_property(variables VARIABLES)
list(TRANSFORM variables APPLY [[set(${item} "${item}=${${item}}")]])
list(JOIN variables "\n  " out)
message(STATUS "Currently defined variables:\n${out}")

Getting that kind of syntax/feature into CMake is a much larger task. It’s unlikely to happen as it has the same parser mixing I mentioned in this comment.

I am not sure if you are proposing something that CMake already supports or something it could support. I am unable to find documentation for the PREDICATE option.

It’s a feature proposal. Sorry about that. English is subtle sometimes and I’m prone to using that at times; I should have made it clearer. “a use case for FOO” would mention an existing feature, but “a use case for a FOO” proposes a new one (by my interpretation at least).

I’ve filed a feature request for this support.