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>
20 #include <gtest/gtest.h>
22 using namespace folly;
24 TEST(NodeTest, Padding) {
25 typedef padded::Node<int32_t, 64> IntNode;
26 EXPECT_EQ(16, IntNode::kElementCount);
27 EXPECT_EQ(0, IntNode::kPaddingBytes);
28 EXPECT_EQ(alignof(int32_t), alignof(IntNode));
29 EXPECT_EQ(64, sizeof(IntNode));
30 EXPECT_EQ(0, IntNode::nodeCount(0));
31 EXPECT_EQ(0, IntNode::paddedByteSize(0));
32 EXPECT_EQ(0, IntNode::unpaddedByteSize(0));
33 EXPECT_EQ(1, IntNode::nodeCount(1));
34 EXPECT_EQ(64, IntNode::paddedByteSize(1));
35 EXPECT_EQ(4, IntNode::unpaddedByteSize(1));
36 EXPECT_EQ(1, IntNode::nodeCount(16));
37 EXPECT_EQ(64, IntNode::paddedByteSize(16));
38 EXPECT_EQ(64, IntNode::unpaddedByteSize(16));
39 EXPECT_EQ(2, IntNode::nodeCount(17));
40 EXPECT_EQ(128, IntNode::paddedByteSize(17));
41 EXPECT_EQ(68, IntNode::unpaddedByteSize(17));
42 EXPECT_EQ(128, IntNode::paddedByteSize(32));
43 EXPECT_EQ(128, IntNode::unpaddedByteSize(32));
44 EXPECT_EQ(3, IntNode::nodeCount(33));
45 EXPECT_EQ(192, IntNode::paddedByteSize(33));
46 EXPECT_EQ(132, IntNode::unpaddedByteSize(33));
51 EXPECT_EQ(1, alignof(SevenBytes));
52 typedef padded::Node<SevenBytes, 64> SevenByteNode;
53 EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7
54 EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7
55 EXPECT_EQ(1, alignof(SevenByteNode));
56 EXPECT_EQ(64, sizeof(SevenByteNode));
57 EXPECT_EQ(0, SevenByteNode::nodeCount(0));
58 EXPECT_EQ(0, SevenByteNode::paddedByteSize(0));
59 EXPECT_EQ(0, SevenByteNode::unpaddedByteSize(0));
60 EXPECT_EQ(1, SevenByteNode::nodeCount(1));
61 EXPECT_EQ(64, SevenByteNode::paddedByteSize(1));
62 EXPECT_EQ(7, SevenByteNode::unpaddedByteSize(1));
63 EXPECT_EQ(1, SevenByteNode::nodeCount(9));
64 EXPECT_EQ(64, SevenByteNode::paddedByteSize(9));
65 EXPECT_EQ(63, SevenByteNode::unpaddedByteSize(9));
66 EXPECT_EQ(2, SevenByteNode::nodeCount(10));
67 EXPECT_EQ(128, SevenByteNode::paddedByteSize(10));
68 EXPECT_EQ(71, SevenByteNode::unpaddedByteSize(10));
69 EXPECT_EQ(2, SevenByteNode::nodeCount(18));
70 EXPECT_EQ(128, SevenByteNode::paddedByteSize(18));
71 EXPECT_EQ(127, SevenByteNode::unpaddedByteSize(18));
72 EXPECT_EQ(3, SevenByteNode::nodeCount(19));
73 EXPECT_EQ(192, SevenByteNode::paddedByteSize(19));
74 EXPECT_EQ(135, SevenByteNode::unpaddedByteSize(19));
77 class IntPaddedTestBase : public ::testing::Test {
79 typedef padded::Node<uint32_t, 64> IntNode;
80 typedef std::vector<IntNode> IntNodeVec;
85 class IntPaddedConstTest : public IntPaddedTestBase {
87 void SetUp() override {
90 for (int i = 0; i < 4; i++) {
91 for (size_t j = 0; j < IntNode::kElementCount; ++j, ++n_) {
98 TEST_F(IntPaddedConstTest, Iteration) {
100 for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
106 TEST_F(IntPaddedConstTest, Arithmetic) {
107 EXPECT_EQ(64, padded::cend(v_) - padded::cbegin(v_));
108 // Play around block boundaries
109 auto it = padded::cbegin(v_);
113 EXPECT_EQ(0, i2 - it);
116 EXPECT_EQ(1, i2 - it);
117 EXPECT_EQ(-1, it - i2);
125 EXPECT_EQ(1, i2 - it);
126 EXPECT_EQ(-1, it - i2);
134 EXPECT_EQ(-1, i2 - it);
135 EXPECT_EQ(1, it - i2);
143 EXPECT_EQ(-1, i2 - it);
144 EXPECT_EQ(1, it - i2);
148 class IntPaddedNonConstTest : public IntPaddedTestBase {
151 TEST_F(IntPaddedNonConstTest, Iteration) {
156 for (auto it = padded::begin(v_); it != padded::end(v_); ++it, ++k) {
162 for (int i = 0; i < 4; i++) {
163 for (size_t j = 0; j < IntNode::kElementCount; ++j, ++k) {
164 EXPECT_EQ(k, v_[i].data()[j]);
169 class StructPaddedTestBase : public ::testing::Test {
176 typedef padded::Node<Point, 64> PointNode;
177 typedef std::vector<PointNode> PointNodeVec;
182 class StructPaddedConstTest : public StructPaddedTestBase {
184 void SetUp() override {
187 for (int i = 0; i < 4; i++) {
188 for (size_t j = 0; j < PointNode::kElementCount; ++j, ++n_) {
189 auto& point = v_[i].data()[j];
198 TEST_F(StructPaddedConstTest, Iteration) {
200 for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
202 EXPECT_EQ(k + 1, it->y);
203 EXPECT_EQ(k + 2, it->z);
208 class IntAdaptorTest : public IntPaddedConstTest {
210 typedef padded::Adaptor<IntNodeVec> IntAdaptor;
214 TEST_F(IntAdaptorTest, Simple) {
215 for (int i = 0; i < n_; ++i) {
216 EXPECT_EQ((i == 0), a_.empty());
217 EXPECT_EQ(i, a_.size());
220 EXPECT_EQ(n_, a_.size());
223 for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
230 EXPECT_TRUE(a_.empty());
231 EXPECT_EQ(16, p.second);
232 EXPECT_TRUE(v_ == p.first);
235 TEST_F(IntAdaptorTest, ResizeConstructor) {
236 IntAdaptor a(n_, 42);
237 EXPECT_EQ(n_, a.size());
238 for (int i = 0; i < n_; ++i) {
243 TEST_F(IntAdaptorTest, SimpleEmplaceBack) {
244 for (int i = 0; i < n_; ++i) {
245 EXPECT_EQ((i == 0), a_.empty());
246 EXPECT_EQ(i, a_.size());
249 EXPECT_EQ(n_, a_.size());
252 for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
259 EXPECT_TRUE(a_.empty());
260 EXPECT_EQ(16, p.second);
261 EXPECT_TRUE(v_ == p.first);