diff --git a/src/buffer/out/AttrRow.cpp b/src/buffer/out/AttrRow.cpp index 548999bccc..5df4da3978 100644 --- a/src/buffer/out/AttrRow.cpp +++ b/src/buffer/out/AttrRow.cpp @@ -250,7 +250,7 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt if (newAttrs.size() == 1) { // Get the new color attribute we're trying to apply - const TextAttribute NewAttr = gsl::at(newAttrs, 0).GetAttributes(); + const TextAttribute NewAttr = til::at(newAttrs, 0).GetAttributes(); // If the existing run was only 1 element... // ...and the new color is the same as the old, we don't have to do anything and can exit quick. diff --git a/src/buffer/out/OutputCellIterator.cpp b/src/buffer/out/OutputCellIterator.cpp index 9dc5b14574..d32087fe9e 100644 --- a/src/buffer/out/OutputCellIterator.cpp +++ b/src/buffer/out/OutputCellIterator.cpp @@ -114,7 +114,7 @@ OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const // - legacyAttrs - One legacy color item per cell OutputCellIterator::OutputCellIterator(const gsl::span legacyAttrs) noexcept : _mode(Mode::LegacyAttr), - _currentView(s_GenerateViewLegacyAttr(gsl::at(legacyAttrs, 0))), + _currentView(s_GenerateViewLegacyAttr(til::at(legacyAttrs, 0))), _run(legacyAttrs), _attr(InvalidTextAttribute), _distance(0), @@ -129,7 +129,7 @@ OutputCellIterator::OutputCellIterator(const gsl::span legacyAttrs) // - charInfos - Multiple cell with unicode text and legacy color data. OutputCellIterator::OutputCellIterator(const gsl::span charInfos) noexcept : _mode(Mode::CharInfo), - _currentView(s_GenerateView(gsl::at(charInfos, 0))), + _currentView(s_GenerateView(til::at(charInfos, 0))), _run(charInfos), _attr(InvalidTextAttribute), _distance(0), @@ -144,7 +144,7 @@ OutputCellIterator::OutputCellIterator(const gsl::span charInfo // - cells - Multiple cells in a run OutputCellIterator::OutputCellIterator(const gsl::span cells) : _mode(Mode::Cell), - _currentView(s_GenerateView(gsl::at(cells, 0))), + _currentView(s_GenerateView(til::at(cells, 0))), _run(cells), _attr(InvalidTextAttribute), _distance(0), @@ -265,7 +265,7 @@ OutputCellIterator& OutputCellIterator::operator++() _pos++; if (operator bool()) { - _currentView = s_GenerateView(gsl::at(std::get>(_run), _pos)); + _currentView = s_GenerateView(til::at(std::get>(_run), _pos)); } break; } @@ -275,7 +275,7 @@ OutputCellIterator& OutputCellIterator::operator++() _pos++; if (operator bool()) { - _currentView = s_GenerateView(gsl::at(std::get>(_run), _pos)); + _currentView = s_GenerateView(til::at(std::get>(_run), _pos)); } break; } @@ -285,7 +285,7 @@ OutputCellIterator& OutputCellIterator::operator++() _pos++; if (operator bool()) { - _currentView = s_GenerateViewLegacyAttr(gsl::at(std::get>(_run), _pos)); + _currentView = s_GenerateViewLegacyAttr(til::at(std::get>(_run), _pos)); } break; } diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp index e340e198ab..2040502298 100644 --- a/src/buffer/out/TextColor.cpp +++ b/src/buffer/out/TextColor.cpp @@ -158,9 +158,9 @@ COLORREF TextColor::GetColor(gsl::span colorTable, // If we find a match, return instead the bright version of this color for (size_t i = 0; i < 8; i++) { - if (gsl::at(colorTable, i) == defaultColor) + if (til::at(colorTable, i) == defaultColor) { - return gsl::at(colorTable, i + 8); + return til::at(colorTable, i + 8); } } } @@ -173,11 +173,11 @@ COLORREF TextColor::GetColor(gsl::span colorTable, } else if (IsIndex16() && brighten) { - return gsl::at(colorTable, _index | 8); + return til::at(colorTable, _index | 8); } else { - return gsl::at(colorTable, _index); + return til::at(colorTable, _index); } } diff --git a/src/host/alias.cpp b/src/host/alias.cpp index 5c44a843ab..e58fbdb0e9 100644 --- a/src/host/alias.cpp +++ b/src/host/alias.cpp @@ -149,7 +149,7 @@ std::unordered_mapsize() > 0) { - gsl::at(*target, 0) = UNICODE_NULL; + til::at(*target, 0) = UNICODE_NULL; } std::wstring exeNameString(exeName); @@ -211,7 +211,7 @@ std::unordered_map 0) { - gsl::at(target, 0) = ANSI_NULL; + til::at(target, 0) = ANSI_NULL; } LockConsole(); @@ -451,7 +451,7 @@ void Alias::s_ClearCmdExeAliases() if (aliasBuffer.has_value() && aliasBuffer->size() > 0) { - gsl::at(*aliasBuffer, 0) = UNICODE_NULL; + til::at(*aliasBuffer, 0) = UNICODE_NULL; } std::wstring exeNameString(exeName); @@ -543,7 +543,7 @@ void Alias::s_ClearCmdExeAliases() { if (alias.size() > 0) { - gsl::at(alias, 0) = '\0'; + til::at(alias, 0) = '\0'; } LockConsole(); @@ -698,7 +698,7 @@ void Alias::s_ClearCmdExeAliases() writtenOrNeeded = 0; if (aliasExesBuffer.has_value() && aliasExesBuffer->size() > 0) { - gsl::at(*aliasExesBuffer, 0) = UNICODE_NULL; + til::at(*aliasExesBuffer, 0) = UNICODE_NULL; } LPWSTR AliasExesBufferPtrW = aliasExesBuffer.has_value() ? aliasExesBuffer->data() : nullptr; @@ -761,7 +761,7 @@ void Alias::s_ClearCmdExeAliases() { if (aliasExes.size() > 0) { - gsl::at(aliasExes, 0) = '\0'; + til::at(aliasExes, 0) = '\0'; } LockConsole(); diff --git a/src/host/dbcs.cpp b/src/host/dbcs.cpp index fc4fd4586c..eebfcf52a7 100644 --- a/src/host/dbcs.cpp +++ b/src/host/dbcs.cpp @@ -67,10 +67,10 @@ DWORD UnicodeRasterFontCellMungeOnRead(const gsl::span buffer) for (DWORD iSrc = 0; iSrc < buffer.size(); iSrc++) { // If it's not a trailing byte, copy it straight over, stripping out the Leading/Trailing flags from the attributes field. - auto& src{ gsl::at(buffer, iSrc) }; + auto& src{ til::at(buffer, iSrc) }; if (!WI_IsFlagSet(src.Attributes, COMMON_LVB_TRAILING_BYTE)) { - auto& dst{ gsl::at(buffer, iDst) }; + auto& dst{ til::at(buffer, iDst) }; dst = src; WI_ClearAllFlags(dst.Attributes, COMMON_LVB_SBCSDBCS); iDst++; diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 77c830aedf..9c2d0e2649 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1604,7 +1604,7 @@ void DoSrvPrivateRefreshWindow(_In_ const SCREEN_INFORMATION& screenInfo) if (title.has_value() && title->size() > 0) { - gsl::at(*title, 0) = ANSI_NULL; + til::at(*title, 0) = ANSI_NULL; } // Get the appropriate title and length depending on the mode. @@ -1667,7 +1667,7 @@ void DoSrvPrivateRefreshWindow(_In_ const SCREEN_INFORMATION& screenInfo) if (title.size() > 0) { - gsl::at(title, 0) = ANSI_NULL; + til::at(title, 0) = ANSI_NULL; } // Figure out how big our temporary Unicode buffer must be to get the title. @@ -1722,7 +1722,7 @@ void DoSrvPrivateRefreshWindow(_In_ const SCREEN_INFORMATION& screenInfo) // If we didn't copy anything back and there is space, null terminate the given buffer and return. if (title.size() > 0) { - gsl::at(title, 0) = ANSI_NULL; + til::at(title, 0) = ANSI_NULL; written = 1; } } diff --git a/src/host/history.cpp b/src/host/history.cpp index 7475213126..e9da38a2a2 100644 --- a/src/host/history.cpp +++ b/src/host/history.cpp @@ -782,7 +782,7 @@ HRESULT GetConsoleCommandHistoryWImplHelper(const std::wstring_view exeName, writtenOrNeeded = 0; if (historyBuffer.size() > 0) { - gsl::at(historyBuffer, 0) = UNICODE_NULL; + til::at(historyBuffer, 0) = UNICODE_NULL; } CommandHistory* const CommandHistory = CommandHistory::s_FindByExe(exeName); @@ -859,7 +859,7 @@ HRESULT ApiRoutines::GetConsoleCommandHistoryAImpl(const std::string_view exeNam { if (commandHistory.size() > 0) { - gsl::at(commandHistory, 0) = ANSI_NULL; + til::at(commandHistory, 0) = ANSI_NULL; } LockConsole(); diff --git a/src/inc/til/at.h b/src/inc/til/at.h index 56001dfe87..f08f7bb08b 100644 --- a/src/inc/til/at.h +++ b/src/inc/til/at.h @@ -5,17 +5,52 @@ namespace til { + namespace details + { + // This was lifted from gsl::details::is_span. + template + struct is_span_oracle : std::false_type + { + }; + +#ifdef GSL_SPAN_H + template + struct is_span_oracle> : std::true_type + { + }; +#endif + + template + struct is_span : public is_span_oracle> + { + }; + } + // 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 + // This template is explicitly disabled if T is of type gsl::span, as it would interfere with + // the overload below. + template::value, int> = 0> 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]; } + +#ifdef GSL_SPAN_H + // This is an overload of til::at for span that access its backing buffer directly (UNCHECKED) + template + constexpr auto at(gsl::span span, const std::ptrdiff_t i) -> decltype(span[span.size()]) + { +#pragma warning(suppress : 26481) // Suppress bounds.1 check for doing pointer arithmetic +#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 span.data()[i]; + } +#endif } diff --git a/src/renderer/gdi/paint.cpp b/src/renderer/gdi/paint.cpp index 1b68dafc93..b416510f99 100644 --- a/src/renderer/gdi/paint.cpp +++ b/src/renderer/gdi/paint.cpp @@ -316,7 +316,7 @@ using namespace Microsoft::Console::Render; // Convert data from clusters into the text array and the widths array. for (size_t i = 0; i < cchLine; i++) { - const auto& cluster = gsl::at(clusters, i); + const auto& cluster = til::at(clusters, i); // Our GDI renderer hasn't and isn't going to handle things above U+FFFF or sequences. // So replace anything complicated with a replacement character for drawing purposes. diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index 55188cdb6d..59f34e20ab 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -395,7 +395,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // Handle intermediate characters, if any if (!intermediates.empty()) { - switch (static_cast(gsl::at(intermediates, 0))) + switch (static_cast(til::at(intermediates, 0))) { case CsiIntermediateCodes::MOUSE_SGR: { @@ -805,7 +805,7 @@ DWORD InputStateMachineEngine::_GetCursorKeysModifierState(const gsl::span= 2) { - modifiers = _GetModifier(gsl::at(parameters, 1)); + modifiers = _GetModifier(til::at(parameters, 1)); } // Enhanced Keys (from https://docs.microsoft.com/en-us/windows/console/key-event-record-str): @@ -834,7 +834,7 @@ DWORD InputStateMachineEngine::_GetGenericKeysModifierState(const gsl::span= 2) { - modifiers = _GetModifier(gsl::at(parameters, 1)); + modifiers = _GetModifier(til::at(parameters, 1)); } // Enhanced Keys (from https://docs.microsoft.com/en-us/windows/console/key-event-record-str): @@ -1347,22 +1347,22 @@ bool InputStateMachineEngine::_GenerateWin32Key(const gsl::span pa switch (parameters.size()) { case 6: - key.SetRepeatCount(::base::saturated_cast(gsl::at(parameters, 5))); + key.SetRepeatCount(::base::saturated_cast(til::at(parameters, 5))); [[fallthrough]]; case 5: - key.SetActiveModifierKeys(::base::saturated_cast(gsl::at(parameters, 4))); + key.SetActiveModifierKeys(::base::saturated_cast(til::at(parameters, 4))); [[fallthrough]]; case 4: - key.SetKeyDown(static_cast(gsl::at(parameters, 3))); + key.SetKeyDown(static_cast(til::at(parameters, 3))); [[fallthrough]]; case 3: - key.SetCharData(static_cast(gsl::at(parameters, 2))); + key.SetCharData(static_cast(til::at(parameters, 2))); [[fallthrough]]; case 2: - key.SetVirtualScanCode(::base::saturated_cast(gsl::at(parameters, 1))); + key.SetVirtualScanCode(::base::saturated_cast(til::at(parameters, 1))); [[fallthrough]]; case 1: - key.SetVirtualKeyCode(::base::saturated_cast(gsl::at(parameters, 0))); + key.SetVirtualKeyCode(::base::saturated_cast(til::at(parameters, 0))); break; } diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 363221cacc..4d5b4d0c8a 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -403,9 +403,9 @@ bool OutputStateMachineEngine::_IntermediateScsDispatch(const wchar_t wch, // If we have more than one intermediate, the second intermediate forms part of // the charset identifier. Otherwise it's identified by just the final character. - const auto charset = intermediates.size() > 1 ? std::make_pair(gsl::at(intermediates, 1), wch) : std::make_pair(wch, L'\0'); + const auto charset = intermediates.size() > 1 ? std::make_pair(til::at(intermediates, 1), wch) : std::make_pair(wch, L'\0'); - switch (gsl::at(intermediates, 0)) + switch (til::at(intermediates, 0)) { case L'(': success = _dispatch->Designate94Charset(0, charset); @@ -1628,7 +1628,7 @@ bool OutputStateMachineEngine::s_ParseColorSpec(const std::wstring_view string, for (size_t component = 0; component < 3; component++) { bool foundColor = false; - auto& value = gsl::at(colorValues, component); + auto& value = til::at(colorValues, component); for (size_t i = 0; i < 3; i++) { const wchar_t wch = *curr++; diff --git a/src/terminal/parser/ut_parser/InputEngineTest.cpp b/src/terminal/parser/ut_parser/InputEngineTest.cpp index 6873df476a..b97fa263c1 100644 --- a/src/terminal/parser/ut_parser/InputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/InputEngineTest.cpp @@ -369,7 +369,7 @@ bool TestInteractDispatch::WindowManipulation(const DispatchTypes::WindowManipul for (size_t i = 0; i < parameters.size(); i++) { unsigned short actual; - VERIFY_SUCCEEDED(SizeTToUShort(gsl::at(parameters, i), &actual)); + VERIFY_SUCCEEDED(SizeTToUShort(til::at(parameters, i), &actual)); VERIFY_ARE_EQUAL(_testState->_expectedParams[i], actual); } return true; diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 3fed878879..17caebefad 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -1557,14 +1557,14 @@ class StateMachineExternalTest final if (i < expectedOptions.size()) { - expectedOption = gsl::at(expectedOptions, i); + expectedOption = til::at(expectedOptions, i); } - optionsValid = expectedOption == gsl::at(dispatch._options, i); + optionsValid = expectedOption == til::at(dispatch._options, i); if (!optionsValid) { - Log::Comment(NoThrowString().Format(L"Graphics option match failed, index [%zu]. Expected: '%d' Actual: '%d'", i, expectedOption, gsl::at(dispatch._options, i))); + Log::Comment(NoThrowString().Format(L"Graphics option match failed, index [%zu]. Expected: '%d' Actual: '%d'", i, expectedOption, til::at(dispatch._options, i))); break; } } diff --git a/src/types/utils.cpp b/src/types/utils.cpp index 033799de69..86ff8b522a 100644 --- a/src/types/utils.cpp +++ b/src/types/utils.cpp @@ -425,10 +425,10 @@ void Utils::InitializeCampbellColorTableForConhost(const gsl::span tab void Utils::SwapANSIColorOrderForConhost(const gsl::span table) { THROW_HR_IF(E_INVALIDARG, table.size() < 16); - std::swap(gsl::at(table, 1), gsl::at(table, 4)); - std::swap(gsl::at(table, 3), gsl::at(table, 6)); - std::swap(gsl::at(table, 9), gsl::at(table, 12)); - std::swap(gsl::at(table, 11), gsl::at(table, 14)); + std::swap(til::at(table, 1), til::at(table, 4)); + std::swap(til::at(table, 3), til::at(table, 6)); + std::swap(til::at(table, 9), til::at(table, 12)); + std::swap(til::at(table, 11), til::at(table, 14)); } // Function Description: