Skip to content

Commit

Permalink
Add template parameters to WTF::compactMap() to specify resulting vec…
Browse files Browse the repository at this point in the history
…tor inlineCapacity / minCapacity

https://bugs.webkit.org/show_bug.cgi?id=262520

Reviewed by Darin Adler.

Add template parameters to WTF::compactMap() to specify resulting vector inlineCapacity / minCapacity,
similarly to what was done for WTF::map() in 268739@main.

* Source/JavaScriptCore/runtime/JSObject.cpp:
(JSC::JSObject::getOwnIndexedPropertyNames):
* Source/WTF/wtf/Vector.h:
(WTF::CompactMapper::compactMap):
(WTF::compactMap):

Canonical link: https://commits.webkit.org/268790@main
  • Loading branch information
cdumez committed Oct 3, 2023
1 parent 41d4dd4 commit 1517f43
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
13 changes: 5 additions & 8 deletions Source/JavaScriptCore/runtime/JSObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2649,14 +2649,11 @@ void JSObject::getOwnIndexedPropertyNames(JSGlobalObject*, PropertyNameArray& pr
}

if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
Vector<unsigned, 0, UnsafeVectorOverflow> keys;
keys.reserveInitialCapacity(map->size());

SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
if (mode == DontEnumPropertiesMode::Include || !(it->value.attributes() & PropertyAttribute::DontEnum))
keys.uncheckedAppend(static_cast<unsigned>(it->key));
}
auto keys = WTF::compactMap<0, UnsafeVectorOverflow>(*map, [mode](auto& entry) ->std::optional<unsigned> {
if (mode == DontEnumPropertiesMode::Include || !(entry.value.attributes() & PropertyAttribute::DontEnum))
return static_cast<unsigned>(entry.key);
return std::nullopt;
});

std::sort(keys.begin(), keys.end());
for (unsigned i = 0; i < keys.size(); ++i)
Expand Down
42 changes: 28 additions & 14 deletions Source/WTF/wtf/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -1871,48 +1871,62 @@ struct CompactMapTraits<RetainPtr<T>> {
static ItemType extractValue(RetainPtr<T>&& returnValue) { return WTFMove(returnValue); }
};

template<typename MapFunction, typename SourceType, typename Enable = void>
template<typename MapFunction, typename DestinationVectorType, typename SourceType, typename Enable = void>
struct CompactMapper {
using SourceItemType = typename CollectionInspector<SourceType>::SourceItemType;
using ResultItemType = typename std::invoke_result<MapFunction, SourceItemType&>::type;
using DestinationItemType = typename CompactMapTraits<ResultItemType>::ItemType;

static Vector<DestinationItemType> compactMap(const SourceType& source, const MapFunction& mapFunction)
static void compactMap(DestinationVectorType& result, const SourceType& source, const MapFunction& mapFunction)
{
Vector<DestinationItemType> result;
for (auto&& item : source) {
auto itemResult = mapFunction(item);
if (CompactMapTraits<ResultItemType>::hasValue(itemResult))
result.append(CompactMapTraits<ResultItemType>::extractValue(WTFMove(itemResult)));
}
result.shrinkToFit();
return result;
}
};

template<typename MapFunction, typename SourceType>
struct CompactMapper<MapFunction, SourceType, typename std::enable_if<std::is_rvalue_reference<SourceType&&>::value>::type> {
template<typename MapFunction, typename DestinationVectorType, typename SourceType>
struct CompactMapper<MapFunction, DestinationVectorType, SourceType, typename std::enable_if<std::is_rvalue_reference<SourceType&&>::value>::type> {
using SourceItemType = typename CollectionInspector<SourceType>::SourceItemType;
using ResultItemType = typename std::invoke_result<MapFunction, SourceItemType&&>::type;
using DestinationItemType = typename CompactMapTraits<ResultItemType>::ItemType;

static Vector<DestinationItemType> compactMap(SourceType&& source, const MapFunction& mapFunction)
static void compactMap(DestinationVectorType& result, SourceType&& source, const MapFunction& mapFunction)
{
Vector<DestinationItemType> result;
for (auto&& item : source) {
auto itemResult = mapFunction(WTFMove(item));
if (CompactMapTraits<ResultItemType>::hasValue(itemResult))
result.append(CompactMapTraits<ResultItemType>::extractValue(WTFMove(itemResult)));
}
result.shrinkToFit();
return result;
}
};

template<typename MapFunction, typename SourceType>
Vector<typename CompactMapper<MapFunction, SourceType>::DestinationItemType> compactMap(SourceType&& source, MapFunction&& mapFunction)
template<size_t inlineCapacity = 0, typename OverflowHandler = CrashOnOverflow, size_t minCapacity = 16, typename MapFunction, typename SourceType>
Vector<typename CompactMapTraits<typename std::invoke_result<MapFunction, typename CollectionInspector<SourceType>::SourceItemType&&>::type>::ItemType, inlineCapacity, OverflowHandler, minCapacity> compactMap(SourceType&& source, MapFunction&& mapFunction)
{
return CompactMapper<MapFunction, SourceType>::compactMap(std::forward<SourceType>(source), std::forward<MapFunction>(mapFunction));
using SourceItemType = typename CollectionInspector<SourceType>::SourceItemType;
using ResultItemType = typename std::invoke_result<MapFunction, SourceItemType&&>::type;
using DestinationItemType = typename CompactMapTraits<ResultItemType>::ItemType;
using DestinationVectorType = Vector<DestinationItemType, inlineCapacity, OverflowHandler, minCapacity>;

DestinationVectorType result;
CompactMapper<MapFunction, DestinationVectorType, SourceType>::compactMap(result, std::forward<SourceType>(source), std::forward<MapFunction>(mapFunction));
return result;
}

template<size_t inlineCapacity = 0, typename OverflowHandler = CrashOnOverflow, size_t minCapacity = 16, typename MapFunction, typename SourceType>
Vector<typename CompactMapTraits<typename std::invoke_result<MapFunction, typename CollectionInspector<SourceType>::SourceItemType&>::type>::ItemType, inlineCapacity, OverflowHandler, minCapacity> compactMap(SourceType& source, MapFunction&& mapFunction)
{
using SourceItemType = typename CollectionInspector<SourceType>::SourceItemType;
using ResultItemType = typename std::invoke_result<MapFunction, SourceItemType&>::type;
using DestinationItemType = typename CompactMapTraits<ResultItemType>::ItemType;
using DestinationVectorType = Vector<DestinationItemType, inlineCapacity, OverflowHandler, minCapacity>;

DestinationVectorType result;
CompactMapper<MapFunction, DestinationVectorType, SourceType&>::compactMap(result, source, std::forward<MapFunction>(mapFunction));
return result;
}

template<typename MapFunction, typename SourceType>
Expand Down

0 comments on commit 1517f43

Please sign in to comment.