forked from mirrors/gecko-dev
Bug 1295611 - Add mozilla::Span. r=froydnj,gerv.
MozReview-Commit-ID: HGNDClVctbE
This commit is contained in:
parent
3905bf8fc4
commit
c514501f1a
10 changed files with 3386 additions and 0 deletions
|
|
@ -238,6 +238,19 @@ AssertedCast(const From aFrom)
|
|||
return static_cast<To>(aFrom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a value of integral type |From| to a value of integral type |To|,
|
||||
* release asserting that the cast will be a safe cast per C++ (that is, that
|
||||
* |to| is in the range of values permitted for the type |From|).
|
||||
*/
|
||||
template<typename To, typename From>
|
||||
inline To
|
||||
ReleaseAssertedCast(const From aFrom)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT((detail::IsInBounds<From, To>(aFrom)));
|
||||
return static_cast<To>(aFrom);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_Casting_h */
|
||||
|
|
|
|||
32
mfbt/Range.h
32
mfbt/Range.h
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
@ -44,6 +45,19 @@ public:
|
|||
mEnd(aOther.mEnd)
|
||||
{}
|
||||
|
||||
MOZ_IMPLICIT Range(Span<T> aSpan)
|
||||
: Range(aSpan.Elements(), aSpan.Length())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename U,
|
||||
class = typename EnableIf<IsConvertible<U (*)[], T (*)[]>::value,
|
||||
int>::Type>
|
||||
MOZ_IMPLICIT Range(const Span<U>& aSpan)
|
||||
: Range(aSpan.Elements(), aSpan.Length())
|
||||
{
|
||||
}
|
||||
|
||||
RangedPtr<T> begin() const { return mStart; }
|
||||
RangedPtr<T> end() const { return mEnd; }
|
||||
size_t length() const { return mEnd - mStart; }
|
||||
|
|
@ -51,8 +65,26 @@ public:
|
|||
T& operator[](size_t aOffset) const { return mStart[aOffset]; }
|
||||
|
||||
explicit operator bool() const { return mStart != nullptr; }
|
||||
|
||||
operator Span<T>() { return Span<T>(mStart.get(), length()); }
|
||||
|
||||
operator Span<const T>() const { return Span<T>(mStart.get(), length()); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Span<T>
|
||||
MakeSpan(Range<T>& aRange)
|
||||
{
|
||||
return aRange;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Span<const T>
|
||||
MakeSpan(const Range<T>& aRange)
|
||||
{
|
||||
return aRange;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_Range_h */
|
||||
|
|
|
|||
1041
mfbt/Span.h
Normal file
1041
mfbt/Span.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -82,6 +82,7 @@ EXPORTS.mozilla = [
|
|||
'SegmentedVector.h',
|
||||
'SHA1.h',
|
||||
'SizePrintfMacros.h',
|
||||
'Span.h',
|
||||
'SplayTree.h',
|
||||
'Sprintf.h',
|
||||
'StaticAnalysisFunctions.h',
|
||||
|
|
|
|||
2079
mfbt/tests/gtest/TestSpan.cpp
Normal file
2079
mfbt/tests/gtest/TestSpan.cpp
Normal file
File diff suppressed because it is too large
Load diff
15
mfbt/tests/gtest/moz.build
Normal file
15
mfbt/tests/gtest/moz.build
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'TestSpan.cpp',
|
||||
]
|
||||
|
||||
#LOCAL_INCLUDES += [
|
||||
# '../../base',
|
||||
#]
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
||||
|
|
@ -4,6 +4,11 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['JS_STANDALONE']:
|
||||
TEST_DIRS += [
|
||||
'gtest',
|
||||
]
|
||||
|
||||
CppUnitTests([
|
||||
'TestArray',
|
||||
'TestArrayUtils',
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@
|
|||
<li><a href="about:license#gears">Google Gears License</a></li>
|
||||
<li><a href="about:license#gears-istumbler">Google Gears/iStumbler License</a></li>
|
||||
<li><a href="about:license#vp8">Google VP8 License</a></li>
|
||||
<li><a href="about:license#gsl">GSL License</a></li>
|
||||
<li><a href="about:license#gyp">gyp License</a></li>
|
||||
<li><a href="about:license#halloc">halloc License</a></li>
|
||||
<li><a href="about:license#harfbuzz">HarfBuzz License</a></li>
|
||||
|
|
@ -3415,6 +3416,38 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1><a id="gsl"></a>GSL License</h1>
|
||||
|
||||
<p>This license applies to <span class="path">mfbt/Span.h</span> and
|
||||
<span class="path">mfbt/tests/gtest/TestSpan.cpp</span>.</p>
|
||||
<!-- https://github.com/Microsoft/GSL/blob/3819df6e378ffccf0e29465afe99c3b324c2aa70/LICENSE -->
|
||||
<pre>
|
||||
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
|
||||
This code is licensed under the MIT License (MIT).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
</pre>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<h1><a id="gyp"></a>gyp License</h1>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "mozilla/Move.h"
|
||||
#include "mozilla/ReverseIterator.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -1116,6 +1117,18 @@ public:
|
|||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
const_reverse_iterator crend() const { return rend(); }
|
||||
|
||||
// Span integration
|
||||
|
||||
operator mozilla::Span<elem_type>()
|
||||
{
|
||||
return mozilla::Span<elem_type>(Elements(), Length());
|
||||
}
|
||||
|
||||
operator mozilla::Span<const elem_type>() const
|
||||
{
|
||||
return mozilla::Span<const elem_type>(Elements(), Length());
|
||||
}
|
||||
|
||||
//
|
||||
// Search methods
|
||||
//
|
||||
|
|
@ -1340,6 +1353,16 @@ protected:
|
|||
return ReplaceElementsAt<Item, ActualAlloc>(
|
||||
aStart, aCount, aArray.Elements(), aArray.Length());
|
||||
}
|
||||
|
||||
template<class Item, typename ActualAlloc = Alloc>
|
||||
elem_type* ReplaceElementsAt(index_type aStart,
|
||||
size_type aCount,
|
||||
mozilla::Span<const Item> aSpan)
|
||||
{
|
||||
return ReplaceElementsAt<Item, ActualAlloc>(
|
||||
aStart, aCount, aSpan.Elements(), aSpan.Length());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template<class Item>
|
||||
|
|
@ -1351,6 +1374,15 @@ public:
|
|||
return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount, aArray);
|
||||
}
|
||||
|
||||
template<class Item>
|
||||
MOZ_MUST_USE elem_type* ReplaceElementsAt(index_type aStart,
|
||||
size_type aCount,
|
||||
mozilla::Span<const Item> aSpan,
|
||||
const mozilla::fallible_t&)
|
||||
{
|
||||
return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount, aSpan);
|
||||
}
|
||||
|
||||
// A variation on the ReplaceElementsAt method defined above.
|
||||
protected:
|
||||
template<class Item, typename ActualAlloc = Alloc>
|
||||
|
|
@ -1403,6 +1435,15 @@ protected:
|
|||
return ReplaceElementsAt<Item, ActualAlloc>(
|
||||
aIndex, 0, aArray.Elements(), aArray.Length());
|
||||
}
|
||||
|
||||
template<class Item, typename ActualAlloc = Alloc>
|
||||
elem_type* InsertElementsAt(index_type aIndex,
|
||||
mozilla::Span<const Item> aSpan)
|
||||
{
|
||||
return ReplaceElementsAt<Item, ActualAlloc>(
|
||||
aIndex, 0, aSpan.Elements(), aSpan.Length());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template<class Item, class Allocator>
|
||||
|
|
@ -1414,6 +1455,14 @@ public:
|
|||
return InsertElementsAt<Item, Allocator, FallibleAlloc>(aIndex, aArray);
|
||||
}
|
||||
|
||||
template<class Item>
|
||||
MOZ_MUST_USE elem_type* InsertElementsAt(index_type aIndex,
|
||||
mozilla::Span<const Item> aSpan,
|
||||
const mozilla::fallible_t&)
|
||||
{
|
||||
return InsertElementsAt<Item, FallibleAlloc>(aIndex, aSpan);
|
||||
}
|
||||
|
||||
// Insert a new element without copy-constructing. This is useful to avoid
|
||||
// temporaries.
|
||||
// @return A pointer to the newly inserted element, or null on OOM.
|
||||
|
|
@ -1548,6 +1597,13 @@ protected:
|
|||
template<class Item, typename ActualAlloc = Alloc>
|
||||
elem_type* AppendElements(const Item* aArray, size_type aArrayLen);
|
||||
|
||||
template<class Item, typename ActualAlloc = Alloc>
|
||||
elem_type* AppendElements(mozilla::Span<const Item> aSpan)
|
||||
{
|
||||
return AppendElements<Item, FallibleAlloc>(aSpan.Elements(),
|
||||
aSpan.Length());
|
||||
}
|
||||
|
||||
template<class Item, size_t Length, typename ActualAlloc = Alloc>
|
||||
elem_type* AppendElements(const mozilla::Array<Item, Length>& aArray)
|
||||
{
|
||||
|
|
@ -1564,6 +1620,15 @@ public:
|
|||
return AppendElements<Item, FallibleAlloc>(aArray, aArrayLen);
|
||||
}
|
||||
|
||||
template<class Item>
|
||||
/* MOZ_MUST_USE */
|
||||
elem_type* AppendElements(mozilla::Span<const Item> aSpan,
|
||||
const mozilla::fallible_t&)
|
||||
{
|
||||
return AppendElements<Item, FallibleAlloc>(aSpan.Elements(),
|
||||
aSpan.Length());
|
||||
}
|
||||
|
||||
// A variation on the AppendElements method defined above.
|
||||
protected:
|
||||
template<class Item, class Allocator, typename ActualAlloc = Alloc>
|
||||
|
|
@ -2397,6 +2462,25 @@ struct nsTArray_CopyChooser<AutoTArray<E, N>>
|
|||
typedef nsTArray_CopyWithConstructors<AutoTArray<E, N>> Type;
|
||||
};
|
||||
|
||||
// Span integration
|
||||
namespace mozilla {
|
||||
|
||||
template<class ElementType, class TArrayAlloc>
|
||||
Span<ElementType>
|
||||
MakeSpan(nsTArray_Impl<ElementType, TArrayAlloc>& aTArray)
|
||||
{
|
||||
return aTArray;
|
||||
}
|
||||
|
||||
template<class ElementType, class TArrayAlloc>
|
||||
Span<const ElementType>
|
||||
MakeSpan(const nsTArray_Impl<ElementType, TArrayAlloc>& aTArray)
|
||||
{
|
||||
return aTArray;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// Assert that AutoTArray doesn't have any extra padding inside.
|
||||
//
|
||||
// It's important that the data stored in this auto array takes up a multiple of
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/IntegerTypeTraits.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
#ifndef MOZILLA_INTERNAL_API
|
||||
#error "Using XPCOM strings is limited to code linked into libxul."
|
||||
|
|
@ -922,6 +924,68 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Span integration
|
||||
*/
|
||||
|
||||
operator mozilla::Span<char_type>()
|
||||
{
|
||||
return mozilla::MakeSpan(BeginWriting(), Length());
|
||||
}
|
||||
|
||||
operator mozilla::Span<const char_type>() const
|
||||
{
|
||||
return mozilla::MakeSpan(BeginReading(), Length());
|
||||
}
|
||||
|
||||
void Append(mozilla::Span<const char_type> aSpan)
|
||||
{
|
||||
auto len = aSpan.Length();
|
||||
MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
|
||||
Append(aSpan.Elements(), len);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool Append(mozilla::Span<const char_type> aSpan,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
auto len = aSpan.Length();
|
||||
if (len > mozilla::MaxValue<size_type>::value) {
|
||||
return false;
|
||||
}
|
||||
return Append(aSpan.Elements(), len, aFallible);
|
||||
}
|
||||
|
||||
#if !defined(CharT_is_PRUnichar)
|
||||
operator mozilla::Span<uint8_t>()
|
||||
{
|
||||
return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()),
|
||||
Length());
|
||||
}
|
||||
|
||||
operator mozilla::Span<const uint8_t>() const
|
||||
{
|
||||
return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(BeginReading()),
|
||||
Length());
|
||||
}
|
||||
|
||||
void Append(mozilla::Span<const uint8_t> aSpan)
|
||||
{
|
||||
auto len = aSpan.Length();
|
||||
MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
|
||||
Append(reinterpret_cast<const char*>(aSpan.Elements()), len);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
auto len = aSpan.Length();
|
||||
if (len > mozilla::MaxValue<size_type>::value) {
|
||||
return false;
|
||||
}
|
||||
return Append(
|
||||
reinterpret_cast<const char*>(aSpan.Elements()), len, aFallible);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* string data is never null, but can be marked void. if true, the
|
||||
|
|
@ -1272,3 +1336,22 @@ public:
|
|||
return mArray[index];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Span integration
|
||||
*/
|
||||
namespace mozilla {
|
||||
|
||||
inline Span<CharT>
|
||||
MakeSpan(nsTSubstring_CharT& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
inline Span<const CharT>
|
||||
MakeSpan(const nsTSubstring_CharT& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
Loading…
Reference in a new issue