| 100 | // the slow implementation if the list is not actually homogeneous. |
| 101 | template <typename ValueType> |
| 102 | absl::Status ListDistinctHomogeneousHashableImpl( |
| 103 | const ListValue& list, |
| 104 | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
| 105 | google::protobuf::MessageFactory* absl_nonnull message_factory, |
| 106 | google::protobuf::Arena* absl_nonnull arena, ListValueBuilder* absl_nonnull builder) { |
| 107 | absl::flat_hash_set<ValueType> seen; |
| 108 | CEL_ASSIGN_OR_RETURN(size_t size, list.Size()); |
| 109 | for (int64_t i = 0; i < size; ++i) { |
| 110 | CEL_ASSIGN_OR_RETURN(Value value, |
| 111 | list.Get(i, descriptor_pool, message_factory, arena)); |
| 112 | if (auto typed_value = value.As<ValueType>(); typed_value.has_value()) { |
| 113 | if (seen.contains(*typed_value)) { |
| 114 | continue; |
| 115 | } |
| 116 | seen.insert(*typed_value); |
| 117 | CEL_RETURN_IF_ERROR(builder->Add(value)); |
| 118 | } else { |
| 119 | // List is not homogeneous, fall back to the slow implementation. |
| 120 | // Keep the existing list builder, which already constructed the list of |
| 121 | // all the distinct values (that were homogeneous so far) up to index i. |
| 122 | // Pass the seen values as a vector to the slow implementation. |
| 123 | std::vector<Value> seen_values{seen.begin(), seen.end()}; |
| 124 | return ListDistinctHeterogeneousImpl(list, descriptor_pool, |
| 125 | message_factory, arena, builder, i, |
| 126 | std::move(seen_values)); |
| 127 | } |
| 128 | } |
| 129 | return absl::OkStatus(); |
| 130 | } |
| 131 | |
| 132 | absl::StatusOr<Value> ListDistinct( |
| 133 | const ListValue& list, |
nothing calls this directly
no test coverage detected