blob: 5c21097d106a192d199d9d84cbaabc1d6a6f3eca [file] [log] [blame]
//===--- EncodedSequenceTest.cpp ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/Basic/EncodedSequence.h"
#include "gtest/gtest.h"
using namespace swift;
namespace {
struct Element {
unsigned X, Y, Z;
static Element decode(const EncodedSequenceBase::Chunk *&ptr) {
auto x = EncodedSequenceBase::decodeIndex(ptr);
auto y = EncodedSequenceBase::decodeIndex(ptr);
auto z = EncodedSequenceBase::decodeIndex(ptr);
return { x, y, z };
}
void encode(EncodedSequenceBase::Chunk *&ptr) const {
EncodedSequenceBase::encodeIndex(X, ptr);
EncodedSequenceBase::encodeIndex(Y, ptr);
EncodedSequenceBase::encodeIndex(Z, ptr);
}
unsigned getEncodedSize() const {
return EncodedSequenceBase::getEncodedIndexSize(X)
+ EncodedSequenceBase::getEncodedIndexSize(Y)
+ EncodedSequenceBase::getEncodedIndexSize(Z);
}
};
enum class DataSet {
None, Small, Big
};
static const DataSet AllDataSets[] = {
DataSet::None,
DataSet::Small,
DataSet::Big,
};
struct Tester {
SmallVector<Element, 4> Vector;
EncodedSequence<Element> Sequence;
Tester() {
EXPECT_TRUE(Sequence.empty());
}
void push_back(Element elt) {
Vector.push_back(elt);
Sequence.push_back(elt);
EXPECT_FALSE(Sequence.empty());
}
// The small data set should use inline storage on any pointer width.
void push_small() {
push_back({ 5, 75, 13 });
check();
}
// The big data set should use out-of-line storage on any pointer width.
void push_big() {
push_back({ 557, 33, 197 });
check();
push_back({ 234897, 3, 0 });
check();
push_back({ 10123, 34987345, 1387123 });
check();
}
void push(DataSet set) {
switch (set) {
case DataSet::None: return;
case DataSet::Small: return push_small();
case DataSet::Big: return push_big();
}
}
void check() {
auto vi = Vector.begin(), ve = Vector.end();
auto si = Sequence.begin(), se = Sequence.end();
while (true) {
if (vi == ve) {
EXPECT_EQ(se, si);
return;
}
auto velt = *vi;
auto selt = *si;
EXPECT_EQ(velt.X, selt.X);
EXPECT_EQ(velt.Y, selt.Y);
EXPECT_EQ(velt.Z, selt.Z);
auto selt2 = *si;
EXPECT_EQ(selt.X, selt2.X);
EXPECT_EQ(selt.Y, selt2.Y);
EXPECT_EQ(selt.Z, selt2.Z);
++vi;
++si;
}
}
};
} // end anonymous namespace
TEST(EncodedSequenceTest, PushIterate) {
Tester tester;
tester.check();
tester.push_back({ 557, 33, 197 });
tester.check();
tester.push_back({ 234897, 3, 0 });
tester.check();
tester.push_back({ 10123, 34987345, 1387123 });
tester.check();
}
static void testCopyCtor(DataSet srcSet) {
Tester src;
src.push(srcSet);
Tester dest = src;
src.check();
dest.check();
}
TEST(EncodedSequenceTest, CopyCtor) {
for (auto srcSet : AllDataSets)
testCopyCtor(srcSet);
}
static void testMoveCtor(DataSet srcSet) {
Tester src;
src.push(srcSet);
Tester dest = std::move(src);
EXPECT_TRUE(src.Sequence.empty());
src.Vector.clear();
src.check();
dest.check();
}
TEST(EncodedSequenceTest, MoveCtor) {
for (auto srcSet : AllDataSets)
testMoveCtor(srcSet);
}
static void testCopyAssign(DataSet destSet, DataSet srcSet) {
Tester src;
src.push(srcSet);
Tester dest;
dest.push(destSet);
dest = src;
src.check();
dest.check();
}
TEST(EncodedSequenceTest, CopyAssign) {
for (auto destSet : AllDataSets)
for (auto srcSet : AllDataSets)
testCopyAssign(destSet, srcSet);
}
static void testMoveAssign(DataSet destSet, DataSet srcSet) {
Tester src;
src.push(srcSet);
Tester dest;
dest.push(destSet);
dest = std::move(src);
EXPECT_TRUE(src.Sequence.empty());
src.Vector.clear();
src.check();
dest.check();
}
TEST(EncodedSequenceTest, MoveAssign) {
for (auto destSet : AllDataSets)
for (auto srcSet : AllDataSets)
testMoveAssign(destSet, srcSet);
}