Bug 1184468 - Add To(T)Array functions that materialize a range into an array. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D109056
This commit is contained in:
Simon Giesecke 2021-03-24 17:51:11 +00:00
parent f86d7ce62b
commit 5b5b39393f
6 changed files with 115 additions and 13 deletions

View File

@ -21,14 +21,14 @@
} \
} while (false)
namespace mozilla::gmp {
static nsTArray<uint8_t> ToArray(const uint8_t* aData, uint32_t aDataSize) {
nsTArray<uint8_t> data;
data.AppendElements(aData, aDataSize);
return data;
}
namespace mozilla::gmp {
GMPRecordImpl::GMPRecordImpl(GMPStorageChild* aOwner, const nsCString& aName,
GMPRecordClient* aClient)
: mName(aName), mClient(aClient), mOwner(aOwner) {}

View File

@ -168,10 +168,17 @@ class nsBaseHashtableValueRange {
auto cbegin() const { return begin(); }
auto cend() const { return end(); }
uint32_t Count() const { return mHashtable.EntryCount(); }
private:
const PLDHashTable& mHashtable;
};
template <typename EntryType>
auto RangeSize(const detail::nsBaseHashtableValueRange<EntryType>& aRange) {
return aRange.Count();
}
} // namespace mozilla::detail
/**

View File

@ -3170,20 +3170,26 @@ class nsTArrayBackInserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
ArrayT* mArray;
class Proxy {
ArrayT& mArray;
public:
explicit Proxy(ArrayT& aArray) : mArray{aArray} {}
template <typename E2>
void operator=(E2&& aValue) {
mArray.AppendElement(std::forward<E2>(aValue));
}
};
public:
explicit nsTArrayBackInserter(ArrayT& aArray) : mArray{&aArray} {}
nsTArrayBackInserter& operator=(const E& aValue) {
mArray->AppendElement(aValue);
return *this;
}
nsTArrayBackInserter& operator=(E&& aValue) {
mArray->AppendElement(std::move(aValue));
return *this;
}
nsTArrayBackInserter& operator*() { return *this; }
// Return a proxy so that nsTArrayBackInserter has the default special member
// functions, and the operator= template is defined in Proxy rather than this
// class (which otherwise breaks with recent MS STL versions).
// See also Bug 1331137, comment 11.
Proxy operator*() { return Proxy(*mArray); }
nsTArrayBackInserter& operator++() { return *this; }
nsTArrayBackInserter& operator++(int) { return *this; }
@ -3241,6 +3247,45 @@ class nsTArrayView {
const Span<element_type> mSpan;
};
template <typename Range, typename = std::enable_if_t<std::is_same_v<
typename std::iterator_traits<
typename Range::iterator>::iterator_category,
std::random_access_iterator_tag>>>
auto RangeSize(const Range& aRange) {
// See https://en.cppreference.com/w/cpp/iterator/begin, section 'User-defined
// overloads'.
using std::begin;
using std::end;
return std::distance(begin(aRange), end(aRange));
}
/**
* Materialize a range as a nsTArray (or a compatible variant, like AutoTArray)
* of an explicitly specified type. The array value type must be implicitly
* convertible from the range's value type.
*/
template <typename Array, typename Range>
auto ToTArray(const Range& aRange) {
using std::begin;
using std::end;
Array res;
res.SetCapacity(RangeSize(aRange));
std::copy(begin(aRange), end(aRange), MakeBackInserter(res));
return res;
}
/**
* Materialize a range as a nsTArray of its (decayed) value type.
*/
template <typename Range>
auto ToArray(const Range& aRange) {
return ToTArray<nsTArray<std::decay_t<
typename std::iterator_traits<typename Range::iterator>::value_type>>>(
aRange);
}
} // namespace mozilla
// MOZ_DBG support

View File

@ -133,6 +133,11 @@ class nsTBaseHashSet : protected nsTHashtable<KeyClass> {
}
};
template <typename KeyClass>
auto RangeSize(const nsTBaseHashSet<KeyClass>& aRange) {
return aRange.Count();
}
class nsCycleCollectionTraversalCallback;
template <class KeyClass>

View File

@ -161,10 +161,17 @@ class nsTHashtableKeyRange {
auto cbegin() const { return begin(); }
auto cend() const { return end(); }
uint32_t Count() const { return mHashtable.EntryCount(); }
private:
const PLDHashTable& mHashtable;
};
template <typename EntryType>
auto RangeSize(const ::detail::nsTHashtableKeyRange<EntryType>& aRange) {
return aRange.Count();
}
} // namespace detail
/**

View File

@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/RefPtr.h"
#include "nsTHashMap.h"
using namespace mozilla;
@ -972,4 +973,41 @@ TEST(TArray, StableSort)
EXPECT_EQ(expected, array);
}
TEST(TArray, ToArray)
{
const auto src = std::array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
nsTArray<int> keys = ToArray(src);
keys.Sort();
EXPECT_EQ((nsTArray<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), keys);
}
// Test this to make sure this properly uses ADL.
TEST(TArray, ToArray_HashMap)
{
nsTHashMap<uint32_t, uint64_t> src;
for (uint32_t i = 0; i < 10; ++i) {
src.InsertOrUpdate(i, i);
}
nsTArray<uint32_t> keys = ToArray(src.Keys());
keys.Sort();
EXPECT_EQ((nsTArray<uint32_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), keys);
}
TEST(TArray, ToTArray)
{
const auto src = std::array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto keys = ToTArray<AutoTArray<uint64_t, 10>>(src);
keys.Sort();
static_assert(std::is_same_v<decltype(keys), AutoTArray<uint64_t, 10>>);
EXPECT_EQ((nsTArray<uint64_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), keys);
}
} // namespace TestTArray