/* * Copyright (C) 2014 Pavel Kirienko */ #pragma once #include #include #include #include #include #include namespace uavcan { template class StaticArray { typedef StaticArray SelfType; public: enum { IsDynamic = 0 }; enum { Size = Size_ }; typedef T RawValueType; typedef typename StorageType::Type ValueType; typedef unsigned int SizeType; private: ValueType data_[Size]; void checkOrAdjustRange(SizeType& pos) const { if (pos < Size) return; #if UAVCAN_EXCEPTIONS throw std::out_of_range(typeid(*this).name()); #else assert(0); pos = Size - 1; // Ha ha #endif } template typename EnableIf::Type initialize(int) { std::fill(begin(), end(), U()); } template void initialize(...) { } public: StaticArray() { initialize(0); } static int encode(const SelfType& array, ScalarCodec& codec) { for (SizeType i = 0; i < Size; i++) { const int res = RawValueType::encode(array.data_[i], codec); if (res <= 0) return res; } return 1; } static int decode(SelfType& array, ScalarCodec& codec) { for (SizeType i = 0; i < Size; i++) { const int res = RawValueType::decode(array.data_[i], codec); if (res <= 0) return res; } return 1; } template bool operator==(const R& rhs) const { return (size() == rhs.size()) && std::equal(begin(), end(), rhs.begin()); } template bool operator!=(const R& rhs) const { return !operator==(rhs); } template bool operator<(const R& rhs) const { return std::lexicographical_compare(begin(), end(), rhs.begin(), rhs.end()); } ValueType& at(SizeType pos) { checkOrAdjustRange(pos); return data_[pos]; } const ValueType& at(SizeType pos) const { checkOrAdjustRange(pos); return data_[pos]; } ValueType& operator[](SizeType pos) { return at(pos); } const ValueType& operator[](SizeType pos) const { return at(pos); } ValueType* begin() { return data_; } ValueType* end() { return data_ + Size; } const ValueType* begin() const { return data_; } const ValueType* end() const { return data_ + Size; } SizeType size() const { return Size; } ValueType* data() { return data_; } const ValueType* data() const { return data_; } /** * STL compatibility */ typedef ValueType value_type; typedef SizeType size_type; typedef ValueType* iterator; typedef const ValueType* const_iterator; }; /// Special case - bit array template class StaticArray, Size_ > : public std::bitset { public: enum { IsDynamic = 0 }; enum { Size = Size_ }; typedef IntegerSpec<1, SignednessUnsigned, CastMode> RawValueType; static int encode(const StaticArray& array, ScalarCodec& codec) { for (std::size_t i = 0; i < Size; i++) { const int res = RawValueType::encode(bool(array[i]), codec); if (res <= 0) return res; } return 1; } static int decode(StaticArray& array, ScalarCodec& codec) { for (std::size_t i = 0; i < Size; i++) { typename StorageType::Type value = 0; const int res = RawValueType::decode(value, codec); array[i] = value; if (res <= 0) return res; } return 1; } }; template class StaticArray; // Invalid instantiation }