terminal/src/inc/til/at.h
Chester Liu 02b120236c
Add support for more OSC color formats (#7578)
* Correct the behaviour of parsing `rgb:R/G/B`. It should be interpreted
  as `RR/GG/BB` instead of `0R/0G/0B`
* Add support for `rgb:RRR/GGG/BBB` and `rgb:RRRR/GGGG/BBBB`. The
  behaviour of 12 bit variants is to repeat the first digit at the end,
  e.g. `rgb:123/456/789` becomes `rgb:1231/4564/7897`.
* Add support for `#` formats. We are following the rules of
  [XParseColor] by interpreting `#RGB` as `R000G000B000`.
* Add support for XOrg app color names, which are supported by xterm, VTE
  and many other terminal emulators.
* Multi-parameter OSC 4 is now supported.
* The chaining of OSC 10-12 is not yet supported. But the parameter
  validation is relaxed by parsing the parameters as multi-params but
  only use the first one, which means `\e]10;rgb:R/G/B;` and
  `\e]10:rgb:R/G/B;invalid` will execute `OSC 10` with the first color
  correctly. This fixes some of the issues mentioned in #942 but not
  all of them.

[XParseColor]: https://linux.die.net/man/3/xparsecolor

Closes #3715
2020-10-14 17:29:10 -07:00

58 lines
2.3 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
namespace til
{
namespace details
{
// This was lifted from gsl::details::is_span.
template<class T>
struct is_span_oracle : std::false_type
{
};
#ifdef GSL_SPAN_H
template<class ElementType, std::size_t Extent>
struct is_span_oracle<gsl::span<ElementType, Extent>> : std::true_type
{
};
#endif
template<class T>
struct is_span : public is_span_oracle<std::remove_cv_t<T>>
{
};
}
// 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.
// This template is explicitly disabled if T is of type gsl::span, as it would interfere with
// the overload below.
template<class T, std::enable_if_t<!details::is_span<T>::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.
#pragma warning(suppress : 26445) // Suppress lifetime check for a reference to gsl::span or std::string_view
return cont[i];
}
#ifdef GSL_SPAN_H
// This is an overload of til::at for span that access its backing buffer directly (UNCHECKED)
template<typename ElementType, size_t Extent>
constexpr auto at(gsl::span<ElementType, Extent> 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
}