Use til::some<T,N> to replace the SomeViewports class (#4174)

<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request

Let's give it a test drive.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #4162 
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Build and run it.
This commit is contained in:
Chester Liu 2020-01-21 04:53:24 +08:00 committed by msftbot[bot]
parent 62765f152e
commit 69f3070417
5 changed files with 37 additions and 44 deletions

View file

@ -3,23 +3,11 @@
#pragma once
#include "til/at.h"
#include "til/some.h"
namespace til // Terminal Implementation Library. Also: "Today I Learned"
{
// The at function declares that you've already sufficiently checked that your array access
// is in range before retrieving an item inside it at an offset.
// This is to save double/triple/quadruple testing in circumstances where you are already
// pivoting on the length of a set and now want to pull elements out of it by offset
// without checking again.
// gsl::at will do the check again. As will .at(). And using [] will have a warning in audit.
template<class T>
constexpr auto at(T& cont, const size_t i) -> decltype(cont[cont.size()])
{
#pragma warning(suppress : 26482) // Suppress bounds.2 check for indexing with constant expressions
#pragma warning(suppress : 26446) // Suppress bounds.4 check for subscript operator.
return cont[i];
}
}
// These sit outside the namespace because they sit outside for WIL too.

21
src/inc/til/at.h Normal file
View file

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
namespace til
{
// The at function declares that you've already sufficiently checked that your array access
// is in range before retrieving an item inside it at an offset.
// This is to save double/triple/quadruple testing in circumstances where you are already
// pivoting on the length of a set and now want to pull elements out of it by offset
// without checking again.
// gsl::at will do the check again. As will .at(). And using [] will have a warning in audit.
template<class T>
constexpr auto at(T& cont, const size_t i) -> decltype(cont[cont.size()])
{
#pragma warning(suppress : 26482) // Suppress bounds.2 check for indexing with constant expressions
#pragma warning(suppress : 26446) // Suppress bounds.4 check for subscript operator.
return cont[i];
}
}

View file

@ -154,7 +154,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
_outOfRange();
}
_array[_used] = val;
til::at(_array, _used) = val;
++_used;
}
@ -168,7 +168,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
--_used;
_array[_used] = 0;
til::at(_array, _used) = 0;
}
[[noreturn]] void _invalidArg() const

View file

@ -16,12 +16,16 @@ Author(s):
namespace Microsoft::Console::Types
{
struct SomeViewports;
class Viewport;
using SomeViewports = til::some<Viewport, 4>;
class Viewport final
{
public:
~Viewport() {}
constexpr Viewport() noexcept :
_sr({ 0, 0, -1, -1 }){};
Viewport(const Viewport& other) noexcept;
Viewport(Viewport&&) = default;
Viewport& operator=(const Viewport&) & = default;
@ -125,28 +129,6 @@ namespace Microsoft::Console::Types
friend class ViewportTests;
#endif
};
struct SomeViewports final
{
unsigned char used{ 0 };
std::array<Viewport, 4> viewports{ Viewport::Empty(), Viewport::Empty(), Viewport::Empty(), Viewport::Empty() };
// These two methods are to make this vaguely look like a std::vector.
// Size is the number of viewports that are valid inside this structure
size_t size() const noexcept { return used; }
// At retrieves a viewport at a particular index. If you retrieve beyond the valid size(),
// it will throw std::out_of_range
const Viewport& at(size_t index) const
{
if (index >= used)
{
throw std::out_of_range("Access attempted beyond valid size.");
}
return viewports.at(index);
}
};
}
inline COORD operator-(const COORD& a, const COORD& b) noexcept

View file

@ -18,7 +18,7 @@ Viewport::Viewport(const Viewport& other) noexcept :
Viewport Viewport::Empty() noexcept
{
return Viewport({ 0, 0, -1, -1 });
return Viewport();
}
Viewport Viewport::FromInclusive(const SMALL_RECT sr) noexcept
@ -895,6 +895,7 @@ Viewport Viewport::ToOrigin() const noexcept
// that was covered by `main` before the regional area of `removeMe` was taken out.
// - You must check that each viewport .IsValid() before using it.
[[nodiscard]] SomeViewports Viewport::Subtract(const Viewport& original, const Viewport& removeMe) noexcept
try
{
SomeViewports result;
@ -907,7 +908,7 @@ Viewport Viewport::ToOrigin() const noexcept
if (!intersection.IsValid())
{
// Just put the original rectangle into the results and return early.
result.viewports.at(result.used++) = original;
result.push_back(original);
}
// If the original rectangle matches the intersection, there is nothing to return.
else if (original != intersection)
@ -1003,27 +1004,28 @@ Viewport Viewport::ToOrigin() const noexcept
if (top.IsValid())
{
result.viewports.at(result.used++) = top;
result.push_back(top);
}
if (bottom.IsValid())
{
result.viewports.at(result.used++) = bottom;
result.push_back(bottom);
}
if (left.IsValid())
{
result.viewports.at(result.used++) = left;
result.push_back(left);
}
if (right.IsValid())
{
result.viewports.at(result.used++) = right;
result.push_back(right);
}
}
return result;
}
CATCH_FAIL_FAST()
// Method Description:
// - Returns true if the rectangle described by this Viewport has internal space