mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
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:
parent
f86d7ce62b
commit
5b5b39393f
@ -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) {}
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user