From 01b45c892db8e2e19282869dda0a6b912c0a5e5a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 24 Feb 2014 14:14:45 +0400 Subject: [PATCH] Dynamic array test --- .../uavcan/internal/marshalling/array.hpp | 3 +- .../internal/marshalling/float_spec.hpp | 1 + .../internal/marshalling/integer_spec.hpp | 1 + .../uavcan/internal/marshalling/type_util.hpp | 1 + libuavcan/test/marshalling/array.cpp | 134 +++++++++++++++++- 5 files changed, 137 insertions(+), 3 deletions(-) diff --git a/libuavcan/include/uavcan/internal/marshalling/array.hpp b/libuavcan/include/uavcan/internal/marshalling/array.hpp index b42b8df672..a1d0db2be4 100644 --- a/libuavcan/include/uavcan/internal/marshalling/array.hpp +++ b/libuavcan/include/uavcan/internal/marshalling/array.hpp @@ -87,7 +87,7 @@ protected: public: SizeType size() const { - assert(size_ <= MaxSize); + assert(size_ ? ((size_ - 1u) <= (MaxSize - 1u)) : 1); // -Werror=type-limits return size_; } @@ -212,6 +212,7 @@ public: enum { IsDynamic = ArrayMode == ArrayModeDynamic }; enum { MaxSize = MaxSize_ }; enum { MinBitLen = IsDynamic ? 0 : (RawValueType::MinBitLen * MaxSize) }; + enum { MaxBitLen = RawValueType::MaxBitLen * MaxSize }; static int encode(const SelfType& array, ScalarCodec& codec) { diff --git a/libuavcan/include/uavcan/internal/marshalling/float_spec.hpp b/libuavcan/include/uavcan/internal/marshalling/float_spec.hpp index 6929e4e785..eed9a5c365 100644 --- a/libuavcan/include/uavcan/internal/marshalling/float_spec.hpp +++ b/libuavcan/include/uavcan/internal/marshalling/float_spec.hpp @@ -100,6 +100,7 @@ class FloatSpec : public IEEE754Limits public: enum { BitLen = BitLen_ }; enum { MinBitLen = BitLen }; + enum { MaxBitLen = BitLen }; typedef typename NativeFloatSelector::Type StorageType; diff --git a/libuavcan/include/uavcan/internal/marshalling/integer_spec.hpp b/libuavcan/include/uavcan/internal/marshalling/integer_spec.hpp index ab5958dbab..32bc1b2283 100644 --- a/libuavcan/include/uavcan/internal/marshalling/integer_spec.hpp +++ b/libuavcan/include/uavcan/internal/marshalling/integer_spec.hpp @@ -25,6 +25,7 @@ class IntegerSpec public: enum { BitLen = BitLen_ }; enum { MinBitLen = BitLen }; + enum { MaxBitLen = BitLen }; typedef typename StaticIf<(BitLen <= 8), typename StaticIf::Result, typename StaticIf<(BitLen <= 16), typename StaticIf::Result, diff --git a/libuavcan/include/uavcan/internal/marshalling/type_util.hpp b/libuavcan/include/uavcan/internal/marshalling/type_util.hpp index 82b28b8d4a..bfcb0f7721 100644 --- a/libuavcan/include/uavcan/internal/marshalling/type_util.hpp +++ b/libuavcan/include/uavcan/internal/marshalling/type_util.hpp @@ -18,6 +18,7 @@ template <> struct IntegerBitLen<0> { enum { Result = 0 }; }; +// TODO: fix template struct StorageTypeImpl { typedef T Type; }; diff --git a/libuavcan/test/marshalling/array.cpp b/libuavcan/test/marshalling/array.cpp index b158915aac..7f7de116fe 100644 --- a/libuavcan/test/marshalling/array.cpp +++ b/libuavcan/test/marshalling/array.cpp @@ -15,6 +15,7 @@ struct CustomType uavcan::ArrayModeDynamic, 5> C; enum { MinBitLen = A::MinBitLen + B::MinBitLen + C::MinBitLen }; + enum { MaxBitLen = A::MaxBitLen + B::MaxBitLen + C::MaxBitLen }; uavcan::StorageType::Type a; uavcan::StorageType::Type b; @@ -64,7 +65,7 @@ struct CustomType }; -TEST(StaticArray, IntegerBitLen) +TEST(Array, IntegerBitLen) { using uavcan::IntegerBitLen; @@ -76,7 +77,7 @@ TEST(StaticArray, IntegerBitLen) } -TEST(StaticArray, Basic) +TEST(Array, Basic) { using uavcan::Array; using uavcan::ArrayModeDynamic; @@ -101,9 +102,11 @@ TEST(StaticArray, Basic) /* * Zero initialization check */ + ASSERT_FALSE(a1.empty()); for (A1::const_iterator it = a1.begin(); it != a1.end(); ++it) ASSERT_EQ(0, *it); + ASSERT_FALSE(a2.empty()); for (A2::const_iterator it = a2.begin(); it != a2.end(); ++it) ASSERT_EQ(0, *it); @@ -112,6 +115,7 @@ TEST(StaticArray, Basic) ASSERT_EQ(0, it->a); ASSERT_EQ(0, it->b); ASSERT_EQ(0, it->c.size()); + ASSERT_TRUE(it->c.empty()); } /* @@ -129,6 +133,8 @@ TEST(StaticArray, Basic) a3[i].b = i; for (int i2 = 0; i2 < 5; i2++) a3[i].c.push_back(i2 & 1); + ASSERT_EQ(5, a3[i].c.size()); + ASSERT_FALSE(a3[i].c.empty()); } /* @@ -202,4 +208,128 @@ TEST(StaticArray, Basic) ASSERT_FALSE(a1 == v1); ASSERT_TRUE(a1 != v1); ASSERT_TRUE(a1 < v1); + + ASSERT_EQ(0, a1.front()); + ASSERT_EQ(3, a1.back()); + + // Boolean vector + std::vector v2; + v2.push_back(false); + v2.push_back(true); + v2.push_back(false); + v2.push_back(true); + v2.push_back(false); + + ASSERT_TRUE(a3[0].c == v2); + ASSERT_FALSE(a3[0].c == v1); + ASSERT_FALSE(a3[0].c != v2); + ASSERT_TRUE(a3[0].c != v1); + + v2[0] = true; + ASSERT_TRUE(a3[0].c != v2); + ASSERT_FALSE(a3[0].c == v2); +} + + +TEST(Array, Dynamic) +{ + using uavcan::Array; + using uavcan::ArrayModeDynamic; + using uavcan::ArrayModeStatic; + using uavcan::IntegerSpec; + using uavcan::FloatSpec; + using uavcan::SignednessSigned; + using uavcan::SignednessUnsigned; + using uavcan::CastModeSaturate; + using uavcan::CastModeTruncate; + + typedef Array, ArrayModeDynamic, 5> A; + typedef Array, ArrayModeDynamic, 255> B; + + A a; + B b; + + ASSERT_TRUE(a.empty()); + ASSERT_TRUE(b.empty()); + + { + uavcan::StaticTransferBuffer<16> buf; + uavcan::BitStream bs_wr(buf); + uavcan::ScalarCodec sc_wr(bs_wr); + + ASSERT_EQ(1, A::encode(a, sc_wr)); + ASSERT_EQ(1, B::encode(b, sc_wr)); + + ASSERT_EQ("000" "00000 000" "00000", bs_wr.toString()); + + uavcan::BitStream bs_rd(buf); + uavcan::ScalarCodec sc_rd(bs_rd); + + ASSERT_EQ(1, A::decode(a, sc_rd)); + ASSERT_EQ(1, B::decode(b, sc_rd)); + + ASSERT_TRUE(a.empty()); + ASSERT_TRUE(b.empty()); + } + + a.push_back(true); + a.push_back(false); + a.push_back(true); + a.push_back(false); + a.push_back(true); + + b.push_back(42); + b.push_back(-42); + + { + uavcan::StaticTransferBuffer<16> buf; + uavcan::BitStream bs_wr(buf); + uavcan::ScalarCodec sc_wr(bs_wr); + + ASSERT_EQ(1, A::encode(a, sc_wr)); + ASSERT_EQ(1, B::encode(b, sc_wr)); + + ASSERT_EQ("10110101 00000010 00101010 11010110", bs_wr.toString()); + + uavcan::BitStream bs_rd(buf); + uavcan::ScalarCodec sc_rd(bs_rd); + + a.clear(); + b.clear(); + ASSERT_TRUE(a.empty()); + ASSERT_TRUE(b.empty()); + + ASSERT_EQ(1, A::decode(a, sc_rd)); + ASSERT_EQ(1, B::decode(b, sc_rd)); + + ASSERT_TRUE(a[0]); + ASSERT_FALSE(a[1]); + ASSERT_TRUE(a[2]); + ASSERT_FALSE(a[3]); + ASSERT_TRUE(a[4]); + + ASSERT_EQ(42, b[0]); + ASSERT_EQ(-42, b[1]); + } + + ASSERT_FALSE(a == b); + ASSERT_FALSE(b == a); + ASSERT_TRUE(a != b); + ASSERT_TRUE(b != a); + + a.resize(0); + b.resize(0); + ASSERT_TRUE(a.empty()); + ASSERT_TRUE(b.empty()); + + a.resize(5, true); + b.resize(255, 72); + ASSERT_EQ(5, a.size()); + ASSERT_EQ(255, b.size()); + + for (int i = 0; i < 5; i++) + ASSERT_TRUE(a[i]); + + for (int i = 0; i < 255; i++) + ASSERT_EQ(72, b[i]); }