2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/Padded.h>
19 #include <glog/logging.h>
21 #include <folly/portability/GTest.h>
23 using namespace folly;
25 TEST(NodeTest, Padding) {
26 typedef padded::Node<int32_t, 64> IntNode;
27 EXPECT_EQ(16, IntNode::kElementCount);
28 EXPECT_EQ(0, IntNode::kPaddingBytes);
29 EXPECT_EQ(alignof(int32_t), alignof(IntNode));
30 EXPECT_EQ(64, sizeof(IntNode));
31 EXPECT_EQ(0, IntNode::nodeCount(0));
32 EXPECT_EQ(0, IntNode::paddedByteSize(0));
33 EXPECT_EQ(0, IntNode::unpaddedByteSize(0));
34 EXPECT_EQ(1, IntNode::nodeCount(1));
35 EXPECT_EQ(64, IntNode::paddedByteSize(1));
36 EXPECT_EQ(4, IntNode::unpaddedByteSize(1));
37 EXPECT_EQ(1, IntNode::nodeCount(16));
38 EXPECT_EQ(64, IntNode::paddedByteSize(16));
39 EXPECT_EQ(64, IntNode::unpaddedByteSize(16));
40 EXPECT_EQ(2, IntNode::nodeCount(17));
41 EXPECT_EQ(128, IntNode::paddedByteSize(17));
42 EXPECT_EQ(68, IntNode::unpaddedByteSize(17));
43 EXPECT_EQ(128, IntNode::paddedByteSize(32));
44 EXPECT_EQ(128, IntNode::unpaddedByteSize(32));
45 EXPECT_EQ(3, IntNode::nodeCount(33));
46 EXPECT_EQ(192, IntNode::paddedByteSize(33));
47 EXPECT_EQ(132, IntNode::unpaddedByteSize(33));
52 EXPECT_EQ(1, alignof(SevenBytes));
53 typedef padded::Node<SevenBytes, 64> SevenByteNode;
54 EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7
55 EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7
56 EXPECT_EQ(1, alignof(SevenByteNode));
57 EXPECT_EQ(64, sizeof(SevenByteNode));
58 EXPECT_EQ(0, SevenByteNode::nodeCount(0));
59 EXPECT_EQ(0, SevenByteNode::paddedByteSize(0));
60 EXPECT_EQ(0, SevenByteNode::unpaddedByteSize(0));
61 EXPECT_EQ(1, SevenByteNode::nodeCount(1));
62 EXPECT_EQ(64, SevenByteNode::paddedByteSize(1));
63 EXPECT_EQ(7, SevenByteNode::unpaddedByteSize(1));
64 EXPECT_EQ(1, SevenByteNode::nodeCount(9));
65 EXPECT_EQ(64, SevenByteNode::paddedByteSize(9));
66 EXPECT_EQ(63, SevenByteNode::unpaddedByteSize(9));
67 EXPECT_EQ(2, SevenByteNode::nodeCount(10));
68 EXPECT_EQ(128, SevenByteNode::paddedByteSize(10));
69 EXPECT_EQ(71, SevenByteNode::unpaddedByteSize(10));
70 EXPECT_EQ(2, SevenByteNode::nodeCount(18));
71 EXPECT_EQ(128, SevenByteNode::paddedByteSize(18));
72 EXPECT_EQ(127, SevenByteNode::unpaddedByteSize(18));
73 EXPECT_EQ(3, SevenByteNode::nodeCount(19));
74 EXPECT_EQ(192, SevenByteNode::paddedByteSize(19));
75 EXPECT_EQ(135, SevenByteNode::unpaddedByteSize(19));
78 class IntPaddedTestBase : public ::testing::Test {
80 typedef padded::Node<uint32_t, 64> IntNode;
81 typedef std::vector<IntNode> IntNodeVec;
86 class IntPaddedConstTest : public IntPaddedTestBase {
88 void SetUp() override {
91 for (int i = 0; i < 4; i++) {
92 for (size_t j = 0; j < IntNode::kElementCount; ++j, ++n_) {
99 TEST_F(IntPaddedConstTest, Iteration) {
101 for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
107 TEST_F(IntPaddedConstTest, Arithmetic) {
108 EXPECT_EQ(64, padded::cend(v_) - padded::cbegin(v_));
109 // Play around block boundaries
110 auto it = padded::cbegin(v_);
114 EXPECT_EQ(0, i2 - it);
117 EXPECT_EQ(1, i2 - it);
118 EXPECT_EQ(-1, it - i2);
126 EXPECT_EQ(1, i2 - it);
127 EXPECT_EQ(-1, it - i2);
135 EXPECT_EQ(-1, i2 - it);
136 EXPECT_EQ(1, it - i2);
144 EXPECT_EQ(-1, i2 - it);
145 EXPECT_EQ(1, it - i2);
149 class IntPaddedNonConstTest : public IntPaddedTestBase {
152 TEST_F(IntPaddedNonConstTest, Iteration) {
157 for (auto it = padded::begin(v_); it != padded::end(v_); ++it, ++k) {
163 for (int i = 0; i < 4; i++) {
164 for (size_t j = 0; j < IntNode::kElementCount; ++j, ++k) {
165 EXPECT_EQ(k, v_[i].data()[j]);
170 class StructPaddedTestBase : public ::testing::Test {
177 typedef padded::Node<Point, 64> PointNode;
178 typedef std::vector<PointNode> PointNodeVec;
183 class StructPaddedConstTest : public StructPaddedTestBase {
185 void SetUp() override {
188 for (int i = 0; i < 4; i++) {
189 for (size_t j = 0; j < PointNode::kElementCount; ++j, ++n_) {
190 auto& point = v_[i].data()[j];
199 TEST_F(StructPaddedConstTest, Iteration) {
201 for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
203 EXPECT_EQ(k + 1, it->y);
204 EXPECT_EQ(k + 2, it->z);
209 class IntAdaptorTest : public IntPaddedConstTest {
211 typedef padded::Adaptor<IntNodeVec> IntAdaptor;
215 TEST_F(IntAdaptorTest, Simple) {
216 for (int i = 0; i < n_; ++i) {
217 EXPECT_EQ((i == 0), a_.empty());
218 EXPECT_EQ(i, a_.size());
221 EXPECT_EQ(n_, a_.size());
224 for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
231 EXPECT_TRUE(a_.empty());
232 EXPECT_EQ(16, p.second);
233 EXPECT_TRUE(v_ == p.first);
236 TEST_F(IntAdaptorTest, ResizeConstructor) {
237 IntAdaptor a(n_, 42);
238 EXPECT_EQ(n_, a.size());
239 for (int i = 0; i < n_; ++i) {
244 TEST_F(IntAdaptorTest, SimpleEmplaceBack) {
245 for (int i = 0; i < n_; ++i) {
246 EXPECT_EQ((i == 0), a_.empty());
247 EXPECT_EQ(i, a_.size());
250 EXPECT_EQ(n_, a_.size());
253 for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
260 EXPECT_TRUE(a_.empty());
261 EXPECT_EQ(16, p.second);
262 EXPECT_TRUE(v_ == p.first);