1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://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, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "utils/span.h" 17 18#include <array> 19#include <gtest/gtest.h> 20#include <memory> 21#include <string> 22#include <vector> 23 24namespace panda::test::span { 25 26template <class T> 27std::string ToString(Span<T> s) 28{ 29 std::ostringstream oss; 30 for (const auto &e : s) { 31 oss << e << " "; 32 } 33 return oss.str(); 34} 35template <class T> 36Span<T> Double(Span<T> s) 37{ 38 for (auto &e : s) { 39 e *= 2; 40 } 41 return s; 42} 43 44TEST(Span, Conversions) 45{ 46 int c[] {1, 2, 3}; 47 std::vector v {4, 5, 6}; 48 const std::vector const_v {-4, -5, -6}; 49 std::array a {7, 8, 9}; 50 size_t sz = 3; 51 auto p = std::make_unique<int[]>(sz); 52 p[0] = 10; 53 p[1] = 11; 54 p[2] = 12; 55 std::string s = " !\""; 56 57 EXPECT_EQ(ToString(Double(Span(c))), "2 4 6 "); 58 EXPECT_EQ(ToString(Double(Span(v))), "8 10 12 "); 59 EXPECT_EQ(ToString(Span(const_v)), "-4 -5 -6 "); 60 EXPECT_EQ(ToString(Double(Span(a))), "14 16 18 "); 61 EXPECT_EQ(ToString(Double(Span(p.get(), sz))), "20 22 24 "); 62 EXPECT_EQ(ToString(Double(Span(p.get(), p.get() + 2))), "40 44 "); 63 EXPECT_EQ(ToString(Double(Span(s))), "@ B D "); 64} 65 66TEST(Span, SubSpan) 67{ 68 int c[] {1, 2, 3, 4, 5}; 69 auto s = Span(c).SubSpan(1, 3); 70 auto f = s.First(2); 71 auto l = s.Last(2); 72 73 EXPECT_EQ(ToString(s), "2 3 4 "); 74 EXPECT_EQ(ToString(f), "2 3 "); 75 EXPECT_EQ(ToString(l), "3 4 "); 76} 77 78TEST(Span, SubSpanT) 79{ 80 { 81 uint8_t buf[] = {1, 1, 1, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0x78, 0x56, 0x34, 0x12, 0xfe, 0xff, 0xff, 0xff}; 82 struct Foo { 83 uint32_t a; 84 int32_t b; 85 }; 86 auto sp = Span(buf); 87#ifndef NDEBUG 88 ASSERT_DEATH(sp.SubSpan<Foo>(4, 3), ".*"); 89 ASSERT_DEATH(sp.SubSpan<Foo>(3, 2), ".*"); 90#endif 91 auto sub_sp = sp.SubSpan<Foo>(4, 2); 92 ASSERT_EQ(sub_sp.size(), 2U); 93 ASSERT_EQ(sub_sp[0].a, 1U); 94 ASSERT_EQ(sub_sp[0].b, 2); 95 ASSERT_EQ(sub_sp[1].a, 0x12345678U); 96 ASSERT_EQ(sub_sp[1].b, -2); 97 } 98 { 99 uint32_t buf[] = {0x01020304, 0x05060708, 0x090a0b0c}; 100 auto sp = Span(buf); 101#ifndef NDEBUG 102 ASSERT_DEATH(sp.SubSpan<uint16_t>(4, 1), ".*"); 103#endif 104 auto sub_sp = sp.SubSpan<uint16_t>(1, 4); 105 ASSERT_EQ(sub_sp.size(), 4U); 106 ASSERT_EQ(sub_sp[0], 0x0708); 107 ASSERT_EQ(sub_sp[1], 0x0506); 108 ASSERT_EQ(sub_sp[2], 0x0b0c); 109 ASSERT_EQ(sub_sp[3], 0x090a); 110 } 111} 112 113TEST(Span, AsBytes) 114{ 115 const int c1[] {1, 2, 3}; 116 int c2[] {4, 5, 6}; 117 auto cs = Span(c1); 118 auto s = Span(c2); 119 EXPECT_EQ(cs.SizeBytes(), 12U); 120 EXPECT_EQ(AsBytes(cs)[sizeof(int)], static_cast<std::byte>(2)); 121 AsWritableBytes(s)[4] = static_cast<std::byte>(1); 122 EXPECT_EQ(s[1], 1); 123} 124 125} // namespace panda::test::span 126