1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bytes/alignment.h"
16
17 #include "pw_unit_test/framework.h"
18
19 namespace pw {
20 namespace {
21
TEST(AlignUp,Zero)22 TEST(AlignUp, Zero) {
23 EXPECT_EQ(0u, AlignUp(0, 1));
24 EXPECT_EQ(0u, AlignUp(0, 2));
25 EXPECT_EQ(0u, AlignUp(0, 15));
26 }
27
TEST(AlignUp,Aligned)28 TEST(AlignUp, Aligned) {
29 for (size_t i = 1; i < 130; ++i) {
30 EXPECT_EQ(i, AlignUp(i, i));
31 EXPECT_EQ(2 * i, AlignUp(2 * i, i));
32 EXPECT_EQ(3 * i, AlignUp(3 * i, i));
33 }
34 }
35
TEST(AlignUp,NonAligned_PowerOf2)36 TEST(AlignUp, NonAligned_PowerOf2) {
37 EXPECT_EQ(32u, AlignUp(1, 32));
38 EXPECT_EQ(32u, AlignUp(31, 32));
39 EXPECT_EQ(64u, AlignUp(33, 32));
40 EXPECT_EQ(64u, AlignUp(45, 32));
41 EXPECT_EQ(64u, AlignUp(63, 32));
42 EXPECT_EQ(128u, AlignUp(127, 32));
43 }
44
TEST(AlignUp,NonAligned_NonPowerOf2)45 TEST(AlignUp, NonAligned_NonPowerOf2) {
46 EXPECT_EQ(2u, AlignUp(1, 2));
47
48 EXPECT_EQ(15u, AlignUp(1, 15));
49 EXPECT_EQ(15u, AlignUp(14, 15));
50 EXPECT_EQ(30u, AlignUp(16, 15));
51 }
52
TEST(AlignDown,Zero)53 TEST(AlignDown, Zero) {
54 EXPECT_EQ(0u, AlignDown(0, 1));
55 EXPECT_EQ(0u, AlignDown(0, 2));
56 EXPECT_EQ(0u, AlignDown(0, 15));
57 }
58
TEST(AlignDown,Aligned)59 TEST(AlignDown, Aligned) {
60 for (size_t i = 1; i < 130; ++i) {
61 EXPECT_EQ(i, AlignDown(i, i));
62 EXPECT_EQ(2 * i, AlignDown(2 * i, i));
63 EXPECT_EQ(3 * i, AlignDown(3 * i, i));
64 }
65 }
66
TEST(AlignDown,NonAligned_PowerOf2)67 TEST(AlignDown, NonAligned_PowerOf2) {
68 EXPECT_EQ(0u, AlignDown(1, 32));
69 EXPECT_EQ(0u, AlignDown(31, 32));
70 EXPECT_EQ(32u, AlignDown(33, 32));
71 EXPECT_EQ(32u, AlignDown(45, 32));
72 EXPECT_EQ(32u, AlignDown(63, 32));
73 EXPECT_EQ(96u, AlignDown(127, 32));
74 }
75
TEST(AlignDown,NonAligned_NonPowerOf2)76 TEST(AlignDown, NonAligned_NonPowerOf2) {
77 EXPECT_EQ(0u, AlignDown(1, 2));
78
79 EXPECT_EQ(0u, AlignDown(1, 15));
80 EXPECT_EQ(0u, AlignDown(14, 15));
81 EXPECT_EQ(15u, AlignDown(16, 15));
82 }
83
TEST(Padding,Zero)84 TEST(Padding, Zero) {
85 EXPECT_EQ(0u, Padding(0, 1));
86 EXPECT_EQ(0u, Padding(0, 2));
87 EXPECT_EQ(0u, Padding(0, 15));
88 }
89
TEST(Padding,Aligned)90 TEST(Padding, Aligned) {
91 for (size_t i = 1; i < 130; ++i) {
92 EXPECT_EQ(0u, Padding(i, i));
93 EXPECT_EQ(0u, Padding(2 * i, i));
94 EXPECT_EQ(0u, Padding(3 * i, i));
95 }
96 }
97
TEST(Padding,NonAligned_PowerOf2)98 TEST(Padding, NonAligned_PowerOf2) {
99 EXPECT_EQ(31u, Padding(1, 32));
100 EXPECT_EQ(1u, Padding(31, 32));
101 EXPECT_EQ(31u, Padding(33, 32));
102 EXPECT_EQ(19u, Padding(45, 32));
103 EXPECT_EQ(1u, Padding(63, 32));
104 EXPECT_EQ(1u, Padding(127, 32));
105 }
106
TEST(Padding,NonAligned_NonPowerOf2)107 TEST(Padding, NonAligned_NonPowerOf2) {
108 EXPECT_EQ(1u, Padding(1, 2));
109
110 EXPECT_EQ(14u, Padding(1, 15));
111 EXPECT_EQ(1u, Padding(14, 15));
112 EXPECT_EQ(14u, Padding(16, 15));
113 }
114
TEST(GetAlignedSubspan,AlignedSpanIsUnchanged)115 TEST(GetAlignedSubspan, AlignedSpanIsUnchanged) {
116 alignas(16) std::array<std::byte, 256> bytes{};
117 pw::ByteSpan aligned = GetAlignedSubspan(bytes, 16);
118 EXPECT_EQ(bytes.data(), aligned.data());
119 EXPECT_EQ(bytes.size(), aligned.size());
120 }
121
TEST(GetAlignedSubspan,UnalignedSpanIsAdvanced)122 TEST(GetAlignedSubspan, UnalignedSpanIsAdvanced) {
123 alignas(16) std::array<std::byte, 256> buffer{};
124 pw::ByteSpan bytes(buffer);
125 bytes = bytes.subspan(1);
126 pw::ByteSpan aligned = GetAlignedSubspan(bytes, 16);
127 EXPECT_EQ(bytes.data() + 15, aligned.data());
128 EXPECT_EQ(bytes.size() - 15, aligned.size());
129 }
130
TEST(GetAlignedSubspan,EmptySpanReturnsEmpty)131 TEST(GetAlignedSubspan, EmptySpanReturnsEmpty) {
132 pw::ByteSpan bytes;
133 pw::ByteSpan aligned = GetAlignedSubspan(bytes, 16);
134 EXPECT_EQ(aligned.size(), 0u);
135 }
136
TEST(GetAlignedSubspan,SpanTooSmallForAlignmentReturnsEmptySpan)137 TEST(GetAlignedSubspan, SpanTooSmallForAlignmentReturnsEmptySpan) {
138 alignas(16) std::array<std::byte, 16> buffer{};
139 pw::ByteSpan bytes(buffer);
140 bytes = bytes.subspan(1);
141 pw::ByteSpan aligned = GetAlignedSubspan(bytes, 16);
142 EXPECT_EQ(aligned.size(), 0u);
143 }
144
145 } // namespace
146 } // namespace pw
147