| 950 | |
| 951 | template <class T> |
| 952 | static bool CheckDuplicateValues(const GDALAlgorithmArg *arg, |
| 953 | const std::vector<T> &values) |
| 954 | { |
| 955 | auto tmpValues = values; |
| 956 | bool bHasDupValues = false; |
| 957 | if constexpr (std::is_floating_point_v<T>) |
| 958 | { |
| 959 | // Avoid undefined behavior with NaN values |
| 960 | std::sort(tmpValues.begin(), tmpValues.end(), |
| 961 | [](T a, T b) |
| 962 | { |
| 963 | if (std::isnan(a) && !std::isnan(b)) |
| 964 | return true; |
| 965 | if (std::isnan(b)) |
| 966 | return false; |
| 967 | return a < b; |
| 968 | }); |
| 969 | |
| 970 | bHasDupValues = |
| 971 | std::adjacent_find(tmpValues.begin(), tmpValues.end(), |
| 972 | [](T a, T b) |
| 973 | { |
| 974 | if (std::isnan(a) && std::isnan(b)) |
| 975 | return true; |
| 976 | return a == b; |
| 977 | }) != tmpValues.end(); |
| 978 | } |
| 979 | else |
| 980 | { |
| 981 | std::sort(tmpValues.begin(), tmpValues.end()); |
| 982 | bHasDupValues = std::adjacent_find(tmpValues.begin(), |
| 983 | tmpValues.end()) != tmpValues.end(); |
| 984 | } |
| 985 | if (bHasDupValues) |
| 986 | { |
| 987 | CPLError(CE_Failure, CPLE_AppDefined, |
| 988 | "'%s' must be a list of unique values.", |
| 989 | arg->GetName().c_str()); |
| 990 | return false; |
| 991 | } |
| 992 | return true; |
| 993 | } |
| 994 | |
| 995 | /************************************************************************/ |
| 996 | /* GDALAlgorithmArg::RunValidationActions() */ |