mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-11 04:38:24 -06:00
Replace til::some with til::small_vector (#16952)
`til::small_vector` had a bug: Its internal backing buffer didn't prevent default initialization! Wrapping it in an `union` fixed that. `til::some` had the same issue, but thinking about it I realized we don't need both classes to exist, so I removed `til::some` since `til::small_vector` is more flexible. Checking the assembly, I noticed that `til::small_vector` with the `union` fix produced a more compact result. I also noticed that in combination with function calls and inlining the bit-wise ANDs in the point/size/rect boolean operators produced poor-ish results. Since their impact on performance is negligible to begin with I simplified that code slightly. Finally, I noticed that the boolean operator for `til::point` was incorrect since it checked for `>0` instead of `>=0`. Luckily nothing seemed to have used that operator yet. (= No inbox regression.)
This commit is contained in:
parent
75dea24d6b
commit
3cc82a51d8
@ -58,7 +58,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return (x > 0) & (y > 0);
|
||||
return x >= 0 && y >= 0;
|
||||
}
|
||||
|
||||
constexpr bool operator<(const point other) const noexcept
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.h"
|
||||
#include "some.h"
|
||||
#include "math.h"
|
||||
#include "size.h"
|
||||
#include "point.h"
|
||||
#include "operators.h"
|
||||
#include "small_vector.h"
|
||||
|
||||
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
{
|
||||
@ -31,8 +31,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
explicit constexpr operator bool() const noexcept
|
||||
{
|
||||
return (left >= 0) & (top >= 0) &
|
||||
(right >= left) & (bottom >= top);
|
||||
return left >= 0 && top >= 0 && right >= left && bottom >= top;
|
||||
}
|
||||
};
|
||||
|
||||
@ -204,8 +203,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
explicit constexpr operator bool() const noexcept
|
||||
{
|
||||
return (left >= 0) & (top >= 0) &
|
||||
(right > left) & (bottom > top);
|
||||
return left >= 0 && top >= 0 && right > left && bottom > top;
|
||||
}
|
||||
|
||||
constexpr const_iterator begin() const
|
||||
@ -294,9 +292,9 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
}
|
||||
|
||||
// - = subtract
|
||||
constexpr some<rect, 4> operator-(const rect& other) const
|
||||
small_vector<rect, 4> operator-(const rect& other) const
|
||||
{
|
||||
some<rect, 4> result;
|
||||
small_vector<rect, 4> result;
|
||||
|
||||
// We could have up to four rectangles describing the area resulting when you take removeMe out of main.
|
||||
// Find the intersection of the two so we know which bits of removeMe are actually applicable
|
||||
@ -566,14 +564,12 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr bool contains(point pt) const noexcept
|
||||
{
|
||||
return (pt.x >= left) & (pt.x < right) &
|
||||
(pt.y >= top) & (pt.y < bottom);
|
||||
return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom;
|
||||
}
|
||||
|
||||
constexpr bool contains(const rect& rc) const noexcept
|
||||
{
|
||||
return (rc.left >= left) & (rc.top >= top) &
|
||||
(rc.right <= right) & (rc.bottom <= bottom);
|
||||
return rc.left >= left && rc.top >= top && rc.right <= right && rc.bottom <= bottom;
|
||||
}
|
||||
|
||||
template<typename T = CoordType>
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "small_vector.h"
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
class RunLengthEncodingTests;
|
||||
#endif
|
||||
|
||||
@ -39,7 +39,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return (width > 0) & (height > 0);
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
constexpr size operator+(const size other) const
|
||||
|
||||
@ -652,7 +652,7 @@ namespace til
|
||||
reference emplace_back(Args&&... args)
|
||||
{
|
||||
const auto new_size = _ensure_fits(1);
|
||||
const auto it = new (_data + _size) T(std::forward<Args>(args)...);
|
||||
const auto it = std::construct_at(_data + _size, std::forward<Args>(args)...);
|
||||
_size = new_size;
|
||||
return *it;
|
||||
}
|
||||
@ -930,7 +930,10 @@ namespace til
|
||||
T* _data;
|
||||
size_t _capacity;
|
||||
size_t _size;
|
||||
T _buffer[N];
|
||||
union
|
||||
{
|
||||
T _buffer[N];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,267 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
{
|
||||
template<class T, size_t N>
|
||||
class some
|
||||
{
|
||||
private:
|
||||
std::array<T, N> _array;
|
||||
size_t _used;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class SomeTests;
|
||||
#endif
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
|
||||
using iterator = typename decltype(_array)::iterator;
|
||||
using const_iterator = typename decltype(_array)::const_iterator;
|
||||
|
||||
using reverse_iterator = typename decltype(_array)::reverse_iterator;
|
||||
using const_reverse_iterator = typename decltype(_array)::const_reverse_iterator;
|
||||
|
||||
constexpr some() noexcept :
|
||||
_array{},
|
||||
_used{ 0 }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr some(std::initializer_list<T> init)
|
||||
{
|
||||
if (init.size() > N)
|
||||
{
|
||||
_invalidArg();
|
||||
}
|
||||
|
||||
std::copy(init.begin(), init.end(), _array.begin());
|
||||
_used = init.size();
|
||||
}
|
||||
|
||||
constexpr bool operator==(const til::some<T, N>& other) const noexcept
|
||||
{
|
||||
return std::equal(cbegin(), cend(), other.cbegin(), other.cend());
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const til::some<T, N>& other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
constexpr void fill(const T& _Value)
|
||||
{
|
||||
_array.fill(_Value);
|
||||
_used = N;
|
||||
}
|
||||
|
||||
constexpr void swap(some& _Other) noexcept(std::is_nothrow_swappable_v<T>)
|
||||
{
|
||||
_array.swap(_Other._array);
|
||||
std::swap(_used, _Other._used);
|
||||
}
|
||||
|
||||
constexpr const_iterator begin() const noexcept
|
||||
{
|
||||
return _array.begin();
|
||||
}
|
||||
|
||||
constexpr const_iterator end() const noexcept
|
||||
{
|
||||
return _array.begin() + _used;
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
|
||||
constexpr const_iterator cend() const noexcept
|
||||
{
|
||||
return end();
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const noexcept
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crend() const noexcept
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
|
||||
constexpr size_type size() const noexcept
|
||||
{
|
||||
return _used;
|
||||
}
|
||||
|
||||
constexpr size_type max_size() const noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
constexpr bool empty() const noexcept
|
||||
{
|
||||
return !_used;
|
||||
}
|
||||
|
||||
constexpr void clear() noexcept
|
||||
{
|
||||
_used = 0;
|
||||
_array = {}; // should free members, if necessary.
|
||||
}
|
||||
|
||||
constexpr const_reference at(size_type pos) const
|
||||
{
|
||||
if (_used <= pos)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
return _array[pos];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type pos) const noexcept
|
||||
{
|
||||
return _array[pos];
|
||||
}
|
||||
|
||||
constexpr const_reference front() const noexcept
|
||||
{
|
||||
return _array[0];
|
||||
}
|
||||
|
||||
constexpr const_reference back() const noexcept
|
||||
{
|
||||
return _array[_used - 1];
|
||||
}
|
||||
|
||||
constexpr const T* data() const noexcept
|
||||
{
|
||||
return _array.data();
|
||||
}
|
||||
|
||||
constexpr void push_back(const T& val)
|
||||
{
|
||||
if (_used >= N)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
til::at(_array, _used) = val;
|
||||
|
||||
++_used;
|
||||
}
|
||||
|
||||
constexpr void push_back(T&& val)
|
||||
{
|
||||
if (_used >= N)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
til::at(_array, _used) = std::move(val);
|
||||
|
||||
++_used;
|
||||
}
|
||||
|
||||
constexpr void pop_back()
|
||||
{
|
||||
if (_used <= 0)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
--_used;
|
||||
|
||||
til::at(_array, _used) = 0;
|
||||
}
|
||||
|
||||
[[noreturn]] constexpr void _invalidArg() const
|
||||
{
|
||||
throw std::invalid_argument("invalid argument");
|
||||
}
|
||||
|
||||
[[noreturn]] constexpr void _outOfRange() const
|
||||
{
|
||||
throw std::out_of_range("invalid some<T, N> subscript");
|
||||
}
|
||||
|
||||
std::wstring to_string() const
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << std::endl
|
||||
<< L"Some contains " << size() << " of max size " << max_size() << ":" << std::endl;
|
||||
wss << L"Elements:" << std::endl;
|
||||
|
||||
for (auto& item : *this)
|
||||
{
|
||||
wss << L"\t- " << item.to_string() << std::endl;
|
||||
}
|
||||
|
||||
return wss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef __WEX_COMMON_H__
|
||||
namespace WEX::TestExecution
|
||||
{
|
||||
template<class T, size_t N>
|
||||
class VerifyOutputTraits<::til::some<T, N>>
|
||||
{
|
||||
public:
|
||||
static WEX::Common::NoThrowString ToString(const ::til::some<T, N>& some)
|
||||
{
|
||||
return WEX::Common::NoThrowString(some.to_string().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, size_t N>
|
||||
class VerifyCompareTraits<::til::some<T, N>, ::til::some<T, N>>
|
||||
{
|
||||
public:
|
||||
static bool AreEqual(const ::til::some<T, N>& expected, const ::til::some<T, N>& actual) noexcept
|
||||
{
|
||||
return expected == actual;
|
||||
}
|
||||
|
||||
static bool AreSame(const ::til::some<T, N>& expected, const ::til::some<T, N>& actual) noexcept
|
||||
{
|
||||
return &expected == &actual;
|
||||
}
|
||||
|
||||
static bool IsLessThan(const ::til::some<T, N>& expectedLess, const ::til::some<T, N>& expectedGreater) = delete;
|
||||
|
||||
static bool IsGreaterThan(const ::til::some<T, N>& expectedGreater, const ::til::some<T, N>& expectedLess) = delete;
|
||||
|
||||
static bool IsNull(const ::til::some<T, N>& object) noexcept
|
||||
{
|
||||
return object == til::some<T, N>{};
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
#include <stb_rect_pack.h>
|
||||
#include <til/flat_set.h>
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#include "Backend.h"
|
||||
|
||||
|
||||
@ -4,8 +4,6 @@
|
||||
#include "precomp.h"
|
||||
#include "gdirenderer.hpp"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#include "../inc/unicode.hpp"
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
@ -20,8 +20,6 @@ Revision History:
|
||||
#include "ApiMessageState.h"
|
||||
#include "IApiRoutines.h"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
class ConsoleProcessHandle;
|
||||
class ConsoleHandleData;
|
||||
|
||||
|
||||
@ -868,7 +868,7 @@ class BitmapTests
|
||||
// C _ D D
|
||||
// _ _ E _
|
||||
// _ F F _
|
||||
til::some<til::rect, 6> expected;
|
||||
std::vector<til::rect> expected;
|
||||
expected.push_back(til::rect{ til::point{ 0, 0 }, til::size{ 2, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 3, 0 }, til::size{ 1, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 0, 1 }, til::size{ 1, 1 } });
|
||||
@ -877,7 +877,7 @@ class BitmapTests
|
||||
expected.push_back(til::rect{ til::point{ 1, 3 }, til::size{ 2, 1 } });
|
||||
|
||||
Log::Comment(L"Run the iterator and collect the runs.");
|
||||
til::some<til::rect, 6> actual;
|
||||
std::vector<til::rect> actual;
|
||||
for (auto run : map.runs())
|
||||
{
|
||||
actual.push_back(run);
|
||||
@ -1006,7 +1006,7 @@ class BitmapTests
|
||||
// C _ D D
|
||||
// _ _ E _
|
||||
// _ F F _
|
||||
til::some<til::rect, 6> expected;
|
||||
std::vector<til::rect> expected;
|
||||
expected.push_back(til::rect{ til::point{ 0, 0 }, til::size{ 2, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 3, 0 }, til::size{ 1, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 0, 1 }, til::size{ 1, 1 } });
|
||||
@ -1015,7 +1015,7 @@ class BitmapTests
|
||||
expected.push_back(til::rect{ til::point{ 1, 3 }, til::size{ 2, 1 } });
|
||||
|
||||
Log::Comment(L"Run the iterator and collect the runs.");
|
||||
til::some<til::rect, 6> actual;
|
||||
std::vector<til::rect> actual;
|
||||
for (auto run : map.runs())
|
||||
{
|
||||
actual.push_back(run);
|
||||
|
||||
@ -221,6 +221,24 @@ class PointTests
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
for (const auto x : values)
|
||||
{
|
||||
for (const auto y : values)
|
||||
{
|
||||
const til::point p{ x, y };
|
||||
const auto expected = x >= 0 && y >= 0;
|
||||
const auto actual = static_cast<bool>(p);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Addition)
|
||||
{
|
||||
Log::Comment(L"Addition of two things that should be in bounds.");
|
||||
|
||||
@ -300,22 +300,26 @@ class RectangleTests
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Data:left", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:top", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:right", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:bottom", L"{0,10}")
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
til::CoordType left, top, right, bottom;
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"left", left));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"top", top));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"right", right));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"bottom", bottom));
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
const auto expected = left < right && top < bottom;
|
||||
const til::rect actual{ left, top, right, bottom };
|
||||
VERIFY_ARE_EQUAL(expected, (bool)actual);
|
||||
for (const auto left : values)
|
||||
{
|
||||
for (const auto top : values)
|
||||
{
|
||||
for (const auto right : values)
|
||||
{
|
||||
for (const auto bottom : values)
|
||||
{
|
||||
const til::rect r{ left, top, right, bottom };
|
||||
const auto expected = left >= 0 && top >= 0 && right > left && bottom > top;
|
||||
const auto actual = static_cast<bool>(r);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(OrUnion)
|
||||
@ -364,7 +368,7 @@ class RectangleTests
|
||||
const auto removal = original;
|
||||
|
||||
// Since it's the same rectangle, nothing's left. We should get no results.
|
||||
const til::some<til::rect, 4> expected;
|
||||
const til::small_vector<til::rect, 4> expected;
|
||||
const auto actual = original - removal;
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
@ -375,7 +379,7 @@ class RectangleTests
|
||||
const til::rect removal{ 12, 12, 15, 15 };
|
||||
|
||||
// Since they don't overlap, we expect the original to be given back.
|
||||
const til::some<til::rect, 4> expected{ original };
|
||||
const til::small_vector<til::rect, 4> expected{ original };
|
||||
const auto actual = original - removal;
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
@ -401,7 +405,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ -12, 3, 15, 15 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top }
|
||||
};
|
||||
const auto actual = original - removal;
|
||||
@ -428,7 +432,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 15, 15 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.top, removal.left, original.bottom }
|
||||
};
|
||||
@ -452,7 +456,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 15, 6 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.bottom, original.right, original.bottom },
|
||||
til::rect{ original.left, removal.top, removal.left, removal.bottom }
|
||||
@ -483,7 +487,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 6, 6 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.bottom, original.right, original.bottom },
|
||||
til::rect{ original.left, removal.top, removal.left, removal.bottom },
|
||||
@ -706,26 +710,6 @@ class RectangleTests
|
||||
VERIFY_ARE_EQUAL(expected, rc.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Data:left", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:top", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:right", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:bottom", L"{0,10}")
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
til::CoordType left, top, right, bottom;
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"left", left));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"top", top));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"right", right));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"bottom", bottom));
|
||||
|
||||
const auto expected = !(left < right && top < bottom);
|
||||
const til::rect actual{ left, top, right, bottom };
|
||||
VERIFY_ARE_EQUAL(expected, actual.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsPoint)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
|
||||
@ -147,26 +147,20 @@ class SizeTests
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
const til::size empty;
|
||||
VERIFY_IS_FALSE(!!empty);
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
const til::size yOnly{ 0, 10 };
|
||||
VERIFY_IS_FALSE(!!yOnly);
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
const til::size xOnly{ 10, 0 };
|
||||
VERIFY_IS_FALSE(!!xOnly);
|
||||
|
||||
const til::size both{ 10, 10 };
|
||||
VERIFY_IS_TRUE(!!both);
|
||||
|
||||
const til::size yNegative{ 10, -10 };
|
||||
VERIFY_IS_FALSE(!!yNegative);
|
||||
|
||||
const til::size xNegative{ -10, 10 };
|
||||
VERIFY_IS_FALSE(!!xNegative);
|
||||
|
||||
const til::size bothNegative{ -10, -10 };
|
||||
VERIFY_IS_FALSE(!!bothNegative);
|
||||
for (const auto width : values)
|
||||
{
|
||||
for (const auto height : values)
|
||||
{
|
||||
const til::size s{ width, height };
|
||||
const auto expected = width > 0 && height > 0;
|
||||
const auto actual = static_cast<bool>(s);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Addition)
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
using namespace std::literals;
|
||||
using namespace WEX::Common;
|
||||
using namespace WEX::Logging;
|
||||
|
||||
@ -1,340 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
using namespace WEX::Common;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
class SomeTests
|
||||
{
|
||||
TEST_CLASS(SomeTests);
|
||||
|
||||
TEST_METHOD(Construct)
|
||||
{
|
||||
Log::Comment(L"Default Constructor");
|
||||
til::some<int, 2> s;
|
||||
|
||||
Log::Comment(L"Valid Initializer List Constructor");
|
||||
til::some<int, 2> t{ 1 };
|
||||
til::some<int, 2> u{ 1, 2 };
|
||||
|
||||
Log::Comment(L"Invalid Initializer List Constructor");
|
||||
auto f = []() {
|
||||
til::some<int, 2> v{ 1, 2, 3 };
|
||||
};
|
||||
|
||||
VERIFY_THROWS(f(), std::invalid_argument);
|
||||
}
|
||||
|
||||
TEST_METHOD(Equality)
|
||||
{
|
||||
til::some<int, 2> a{ 1, 2 };
|
||||
til::some<int, 2> b{ 1, 2 };
|
||||
VERIFY_IS_TRUE(a == b);
|
||||
|
||||
til::some<int, 2> c{ 3, 2 };
|
||||
VERIFY_IS_FALSE(a == c);
|
||||
|
||||
til::some<int, 2> d{ 2, 3 };
|
||||
VERIFY_IS_FALSE(a == d);
|
||||
|
||||
til::some<int, 2> e{ 1 };
|
||||
VERIFY_IS_FALSE(a == e);
|
||||
}
|
||||
|
||||
TEST_METHOD(Inequality)
|
||||
{
|
||||
til::some<int, 2> a{ 1, 2 };
|
||||
til::some<int, 2> b{ 1, 2 };
|
||||
VERIFY_IS_FALSE(a != b);
|
||||
|
||||
til::some<int, 2> c{ 3, 2 };
|
||||
VERIFY_IS_TRUE(a != c);
|
||||
|
||||
til::some<int, 2> d{ 2, 3 };
|
||||
VERIFY_IS_TRUE(a != d);
|
||||
|
||||
til::some<int, 2> e{ 1 };
|
||||
VERIFY_IS_TRUE(a != e);
|
||||
}
|
||||
|
||||
TEST_METHOD(Fill)
|
||||
{
|
||||
til::some<int, 4> s;
|
||||
|
||||
const auto val = 12;
|
||||
s.fill(val);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.max_size(), s.size());
|
||||
|
||||
for (const auto& i : s)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(val, i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Swap)
|
||||
{
|
||||
til::some<int, 4> a;
|
||||
til::some<int, 4> b;
|
||||
|
||||
const auto aVal = 900;
|
||||
a.fill(900);
|
||||
|
||||
const auto bVal = 45;
|
||||
b.push_back(45);
|
||||
|
||||
const auto aSize = a.size();
|
||||
const auto bSize = b.size();
|
||||
|
||||
a.swap(b);
|
||||
|
||||
VERIFY_ARE_EQUAL(aSize, b.size());
|
||||
VERIFY_ARE_EQUAL(bSize, a.size());
|
||||
|
||||
VERIFY_ARE_EQUAL(bVal, a[0]);
|
||||
|
||||
for (const auto& i : b)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(aVal, i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Size)
|
||||
{
|
||||
til::some<int, 2> c;
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, c.size());
|
||||
|
||||
c.push_back(3);
|
||||
VERIFY_ARE_EQUAL(1u, c.size());
|
||||
|
||||
c.push_back(12);
|
||||
VERIFY_ARE_EQUAL(2u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(1u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(0u, c.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(MaxSize)
|
||||
{
|
||||
til::some<int, 2> c;
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.push_back(3);
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.push_back(12);
|
||||
VERIFY_ARE_EQUAL(2u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
}
|
||||
|
||||
TEST_METHOD(PushBack)
|
||||
{
|
||||
til::some<int, 1> s;
|
||||
s.push_back(12);
|
||||
VERIFY_THROWS(s.push_back(12), std::out_of_range);
|
||||
}
|
||||
|
||||
TEST_METHOD(PopBack)
|
||||
{
|
||||
til::some<int, 1> s;
|
||||
VERIFY_THROWS(s.pop_back(), std::out_of_range);
|
||||
|
||||
s.push_back(12);
|
||||
VERIFY_THROWS(s.push_back(12), std::out_of_range);
|
||||
}
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
s.push_back(12);
|
||||
VERIFY_IS_FALSE(s.empty());
|
||||
s.pop_back();
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(Clear)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
s.push_back(12);
|
||||
VERIFY_IS_FALSE(s.empty());
|
||||
VERIFY_ARE_EQUAL(1u, s.size());
|
||||
s.clear();
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
VERIFY_ARE_EQUAL(0u, s.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(ClearFreesMembers)
|
||||
{
|
||||
til::some<std::shared_ptr<int>, 2> s;
|
||||
|
||||
auto a = std::make_shared<int>(4);
|
||||
auto weakA = std::weak_ptr<int>(a);
|
||||
|
||||
auto b = std::make_shared<int>(6);
|
||||
auto weakB = std::weak_ptr<int>(b);
|
||||
|
||||
s.push_back(std::move(a));
|
||||
s.push_back(std::move(b));
|
||||
|
||||
VERIFY_IS_FALSE(weakA.expired());
|
||||
VERIFY_IS_FALSE(weakB.expired());
|
||||
|
||||
s.clear();
|
||||
|
||||
VERIFY_IS_TRUE(weakA.expired());
|
||||
VERIFY_IS_TRUE(weakB.expired());
|
||||
}
|
||||
|
||||
TEST_METHOD(Data)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
const auto one = 1;
|
||||
const auto two = 2;
|
||||
s.push_back(one);
|
||||
s.push_back(two);
|
||||
|
||||
auto data = s.data();
|
||||
|
||||
VERIFY_ARE_EQUAL(one, *data);
|
||||
VERIFY_ARE_EQUAL(two, *(data + 1));
|
||||
}
|
||||
|
||||
TEST_METHOD(FrontBack)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
const auto one = 1;
|
||||
const auto two = 2;
|
||||
s.push_back(one);
|
||||
s.push_back(two);
|
||||
|
||||
VERIFY_ARE_EQUAL(one, s.front());
|
||||
VERIFY_ARE_EQUAL(two, s.back());
|
||||
}
|
||||
|
||||
TEST_METHOD(Indexing)
|
||||
{
|
||||
const auto one = 14;
|
||||
const auto two = 28;
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_THROWS(s.at(0), std::out_of_range);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
auto a = s[0];
|
||||
a = s[1];
|
||||
|
||||
s.push_back(one);
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[1];
|
||||
|
||||
s.push_back(two);
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_ARE_EQUAL(two, s.at(1));
|
||||
VERIFY_ARE_EQUAL(two, s[1]);
|
||||
|
||||
s.pop_back();
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[1];
|
||||
|
||||
s.pop_back();
|
||||
VERIFY_THROWS(s.at(0), std::out_of_range);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[0];
|
||||
a = s[1];
|
||||
}
|
||||
|
||||
TEST_METHOD(ForwardIter)
|
||||
{
|
||||
const int vals[] = { 17, 99 };
|
||||
const int valLength = ARRAYSIZE(vals);
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_ARE_EQUAL(s.begin(), s.end());
|
||||
VERIFY_ARE_EQUAL(s.cbegin(), s.cend());
|
||||
VERIFY_ARE_EQUAL(s.begin(), s.cbegin());
|
||||
VERIFY_ARE_EQUAL(s.end(), s.cend());
|
||||
|
||||
s.push_back(vals[0]);
|
||||
s.push_back(vals[1]);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.begin() + valLength, s.end());
|
||||
VERIFY_ARE_EQUAL(s.cbegin() + valLength, s.cend());
|
||||
|
||||
auto count = 0;
|
||||
for (const auto& i : s)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.cbegin(); i < s.cend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.begin(); i < s.end(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReverseIter)
|
||||
{
|
||||
const int vals[] = { 17, 99 };
|
||||
const int valLength = ARRAYSIZE(vals);
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_ARE_EQUAL(s.rbegin(), s.rend());
|
||||
VERIFY_ARE_EQUAL(s.crbegin(), s.crend());
|
||||
VERIFY_ARE_EQUAL(s.rbegin(), s.crbegin());
|
||||
VERIFY_ARE_EQUAL(s.rend(), s.crend());
|
||||
|
||||
s.push_back(vals[0]);
|
||||
s.push_back(vals[1]);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.rbegin() + valLength, s.rend());
|
||||
VERIFY_ARE_EQUAL(s.crbegin() + valLength, s.crend());
|
||||
|
||||
auto count = 0;
|
||||
for (auto i = s.crbegin(); i < s.crend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.rbegin(); i < s.rend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
}
|
||||
};
|
||||
@ -51,10 +51,10 @@ class UnicodeTests
|
||||
struct Test
|
||||
{
|
||||
std::wstring_view input;
|
||||
til::some<std::wstring_view, 5> expected;
|
||||
std::vector<std::wstring_view> expected;
|
||||
};
|
||||
|
||||
static constexpr std::array tests{
|
||||
const std::array tests{
|
||||
Test{ L"", {} },
|
||||
Test{ L"a", { L"a" } },
|
||||
Test{ L"abc", { L"a", L"b", L"c" } },
|
||||
|
||||
@ -30,7 +30,6 @@ SOURCES = \
|
||||
RunLengthEncodingTests.cpp \
|
||||
SizeTests.cpp \
|
||||
SmallVectorTests.cpp \
|
||||
SomeTests.cpp \
|
||||
StaticMapTests.cpp \
|
||||
string.cpp \
|
||||
u8u16convertTests.cpp \
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
<ClCompile Include="RunLengthEncodingTests.cpp" />
|
||||
<ClCompile Include="SizeTests.cpp" />
|
||||
<ClCompile Include="SmallVectorTests.cpp" />
|
||||
<ClCompile Include="SomeTests.cpp" />
|
||||
<ClCompile Include="SPSCTests.cpp" />
|
||||
<ClCompile Include="StaticMapTests.cpp" />
|
||||
<ClCompile Include="string.cpp" />
|
||||
@ -64,7 +63,6 @@
|
||||
<ClInclude Include="..\..\inc\til\rle.h" />
|
||||
<ClInclude Include="..\..\inc\til\size.h" />
|
||||
<ClInclude Include="..\..\inc\til\small_vector.h" />
|
||||
<ClInclude Include="..\..\inc\til\some.h" />
|
||||
<ClInclude Include="..\..\inc\til\spsc.h" />
|
||||
<ClInclude Include="..\..\inc\til\static_map.h" />
|
||||
<ClInclude Include="..\..\inc\til\string.h" />
|
||||
@ -90,4 +88,4 @@
|
||||
<Import Project="$(SolutionDir)src\common.build.post.props" />
|
||||
<Import Project="$(SolutionDir)src\common.build.tests.props" />
|
||||
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
<ClCompile Include="RunLengthEncodingTests.cpp" />
|
||||
<ClCompile Include="SizeTests.cpp" />
|
||||
<ClCompile Include="SmallVectorTests.cpp" />
|
||||
<ClCompile Include="SomeTests.cpp" />
|
||||
<ClCompile Include="SPSCTests.cpp" />
|
||||
<ClCompile Include="StaticMapTests.cpp" />
|
||||
<ClCompile Include="string.cpp" />
|
||||
@ -96,9 +95,6 @@
|
||||
<ClInclude Include="..\..\inc\til\small_vector.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\inc\til\some.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\inc\til\spsc.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
@ -135,4 +131,4 @@
|
||||
<UniqueIdentifier>{7cf29ba4-d33d-4c3b-82e3-ab73e5a79685}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#define ALT_PRESSED (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
|
||||
#define CTRL_PRESSED (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)
|
||||
#define MOD_PRESSED (SHIFT_PRESSED | ALT_PRESSED | CTRL_PRESSED)
|
||||
|
||||
@ -17,7 +17,7 @@ namespace Microsoft::Console::Types
|
||||
{
|
||||
class Viewport;
|
||||
|
||||
using SomeViewports = til::some<Viewport, 4>;
|
||||
using SomeViewports = til::small_vector<Viewport, 4>;
|
||||
|
||||
class Viewport final
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user