diff --git a/compiler/lib/src/main/scala/codegen/CppWriter/ArrayCppWriter.scala b/compiler/lib/src/main/scala/codegen/CppWriter/ArrayCppWriter.scala index c9d2487cc..aae7ca276 100644 --- a/compiler/lib/src/main/scala/codegen/CppWriter/ArrayCppWriter.scala +++ b/compiler/lib/src/main/scala/codegen/CppWriter/ArrayCppWriter.scala @@ -172,6 +172,26 @@ case class ArrayCppWriter ( private def getConstructorMembers: List[CppDoc.Class.Member] = { val defaultValues = getDefaultValues + // Only write this constructor if the array has more than one element + val singleElementConstructor = + if arraySize == 1 then Nil + else List( + CppDoc.Class.Member.Constructor( + CppDoc.Class.Constructor( + Some("Constructor (single element)"), + List( + CppDoc.Function.Param( + CppDoc.Type("const ElementType&"), + "e", + Some("The element"), + ) + ), + List("Serializable()"), + indexIterator(lines("this->elements[index] = e;")), + ) + ) + ) + List( CppDoc.Class.Member.Lines( CppDoc.Lines( @@ -212,50 +232,39 @@ case class ArrayCppWriter ( List("Serializable()"), indexIterator(lines("this->elements[index] = a[index];")), ) - ), - CppDoc.Class.Member.Constructor( - CppDoc.Class.Constructor( - Some("Constructor (single element)"), - List( - CppDoc.Function.Param( + ) + ) ++ + singleElementConstructor ++ + List( + CppDoc.Class.Member.Constructor( + CppDoc.Class.Constructor( + Some("Constructor (multiple elements)"), + List.range(1, arraySize + 1).map(i => CppDoc.Function.Param( CppDoc.Type("const ElementType&"), - "e", - Some("The element"), - ) - ), - List("Serializable()"), - indexIterator(lines("this->elements[index] = e;")), - ) - ), - CppDoc.Class.Member.Constructor( - CppDoc.Class.Constructor( - Some("Constructor (multiple elements)"), - List.range(1, arraySize + 1).map(i => CppDoc.Function.Param( - CppDoc.Type("const ElementType&"), - s"e$i", - Some(s"Element $i"), - )), - List("Serializable()"), - List.range(1, arraySize + 1).map(i => line( - s"this->elements[${i - 1}] = e$i;" - )), - ) - ), - CppDoc.Class.Member.Constructor( - CppDoc.Class.Constructor( - Some("Copy Constructor"), - List( - CppDoc.Function.Param( - CppDoc.Type(s"const $name&"), - "obj", - Some("The source object"), - ) - ), - List("Serializable()"), - indexIterator(lines("this->elements[index] = obj.elements[index];")), - ) - ), - ) + s"e$i", + Some(s"Element $i"), + )), + List("Serializable()"), + List.range(1, arraySize + 1).map(i => line( + s"this->elements[${i - 1}] = e$i;" + )), + ) + ), + CppDoc.Class.Member.Constructor( + CppDoc.Class.Constructor( + Some("Copy Constructor"), + List( + CppDoc.Function.Param( + CppDoc.Type(s"const $name&"), + "obj", + Some("The source object"), + ) + ), + List("Serializable()"), + indexIterator(lines("this->elements[index] = obj.elements[index];")), + ) + ), + ) } private def getOperatorMembers: List[CppDoc.Class.Member] = diff --git a/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.cpp b/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.cpp new file mode 100644 index 000000000..c7b42bc7a --- /dev/null +++ b/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.cpp @@ -0,0 +1,180 @@ +// ====================================================================== +// \title SingleElementArrayAc.cpp +// \author Generated by fpp-to-cpp +// \brief cpp file for SingleElement array +// ====================================================================== + +#include +#include + +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/StringUtils.hpp" +#include "SingleElementArrayAc.hpp" + +// ---------------------------------------------------------------------- +// Constructors +// ---------------------------------------------------------------------- + +SingleElement :: + SingleElement() : + Serializable() +{ + // Construct using element-wise constructor + *this = SingleElement( + 0 + ); +} + +SingleElement :: + SingleElement(const ElementType (&a)[SIZE]) : + Serializable() +{ + for (U32 index = 0; index < SIZE; index++) { + this->elements[index] = a[index]; + } +} + +SingleElement :: + SingleElement(const ElementType& e1) : + Serializable() +{ + this->elements[0] = e1; +} + +SingleElement :: + SingleElement(const SingleElement& obj) : + Serializable() +{ + for (U32 index = 0; index < SIZE; index++) { + this->elements[index] = obj.elements[index]; + } +} + +// ---------------------------------------------------------------------- +// Operators +// ---------------------------------------------------------------------- + +SingleElement::ElementType& SingleElement :: + operator[](const U32 i) +{ + FW_ASSERT(i < SIZE); + return this->elements[i]; +} + +const SingleElement::ElementType& SingleElement :: + operator[](const U32 i) const +{ + FW_ASSERT(i < SIZE); + return this->elements[i]; +} + +SingleElement& SingleElement :: + operator=(const SingleElement& obj) +{ + if (this == &obj) { + return *this; + } + + for (U32 index = 0; index < SIZE; index++) { + this->elements[index] = obj.elements[index]; + } + return *this; +} + +SingleElement& SingleElement :: + operator=(const ElementType (&a)[SIZE]) +{ + for (U32 index = 0; index < SIZE; index++) { + this->elements[index] = a[index]; + } + return *this; +} + +SingleElement& SingleElement :: + operator=(const ElementType& e) +{ + for (U32 index = 0; index < SIZE; index++) { + this->elements[index] = e; + } + return *this; +} + +bool SingleElement :: + operator==(const SingleElement& obj) const +{ + for (U32 index = 0; index < SIZE; index++) { + if (!((*this)[index] == obj[index])) { + return false; + } + } + return true; +} + +bool SingleElement :: + operator!=(const SingleElement& obj) const +{ + return !(*this == obj); +} + +#ifdef BUILD_UT + +std::ostream& operator<<(std::ostream& os, const SingleElement& obj) { + Fw::String s; + obj.toString(s); + os << s; + return os; +} + +#endif + +// ---------------------------------------------------------------------- +// Member functions +// ---------------------------------------------------------------------- + +Fw::SerializeStatus SingleElement :: + serialize(Fw::SerializeBufferBase& buffer) const +{ + Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; + for (U32 index = 0; index < SIZE; index++) { + status = buffer.serialize((*this)[index]); + if (status != Fw::FW_SERIALIZE_OK) { + return status; + } + } + return status; +} + +Fw::SerializeStatus SingleElement :: + deserialize(Fw::SerializeBufferBase& buffer) +{ + Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; + for (U32 index = 0; index < SIZE; index++) { + status = buffer.deserialize((*this)[index]); + if (status != Fw::FW_SERIALIZE_OK) { + return status; + } + } + return status; +} + +#if FW_ARRAY_TO_STRING || BUILD_UT + +void SingleElement :: + toString(Fw::StringBase& sb) const +{ + static const char *formatString = "[ " + "%" PRIu32 " ]"; + + char outputString[FW_ARRAY_TO_STRING_BUFFER_SIZE]; + (void) snprintf( + outputString, + FW_ARRAY_TO_STRING_BUFFER_SIZE, + formatString, + this->elements[0] + ); + + outputString[FW_ARRAY_TO_STRING_BUFFER_SIZE-1] = 0; // NULL terminate + sb = outputString; +} + +#endif diff --git a/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.hpp b/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.hpp new file mode 100644 index 000000000..4415f0ab0 --- /dev/null +++ b/compiler/tools/fpp-to-cpp/test/array/SingleElementArrayAc.ref.hpp @@ -0,0 +1,152 @@ +// ====================================================================== +// \title SingleElementArrayAc.hpp +// \author Generated by fpp-to-cpp +// \brief hpp file for SingleElement array +// ====================================================================== + +#ifndef SingleElementArrayAc_HPP +#define SingleElementArrayAc_HPP + +#include "FpConfig.hpp" +#include "Fw/Types/Serializable.hpp" +#include "Fw/Types/String.hpp" + +//! An array with one element +class SingleElement : + public Fw::Serializable +{ + + public: + + // ---------------------------------------------------------------------- + // Types + // ---------------------------------------------------------------------- + + //! The element type + typedef U32 ElementType; + + public: + + // ---------------------------------------------------------------------- + // Constants + // ---------------------------------------------------------------------- + + enum { + //! The size of the array + SIZE = 1, + //! The size of the serial representation + SERIALIZED_SIZE = SIZE * sizeof(U32), + }; + + public: + + // ---------------------------------------------------------------------- + // Constructors + // ---------------------------------------------------------------------- + + //! Constructor (default value) + SingleElement(); + + //! Constructor (user-provided value) + SingleElement( + const ElementType (&a)[SIZE] //!< The array + ); + + //! Constructor (multiple elements) + SingleElement( + const ElementType& e1 //!< Element 1 + ); + + //! Copy Constructor + SingleElement( + const SingleElement& obj //!< The source object + ); + + public: + + // ---------------------------------------------------------------------- + // Operators + // ---------------------------------------------------------------------- + + //! Subscript operator + ElementType& operator[]( + const U32 i //!< The subscript index + ); + + //! Const subscript operator + const ElementType& operator[]( + const U32 i //!< The subscript index + ) const; + + //! Copy assignment operator (object) + SingleElement& operator=( + const SingleElement& obj //!< The source object + ); + + //! Copy assignment operator (raw array) + SingleElement& operator=( + const ElementType (&a)[SIZE] //!< The source array + ); + + //! Copy assignment operator (single element) + SingleElement& operator=( + const ElementType& e //!< The element + ); + + //! Equality operator + bool operator==( + const SingleElement& obj //!< The other object + ) const; + + //! Inequality operator + bool operator!=( + const SingleElement& obj //!< The other object + ) const; + +#ifdef BUILD_UT + + //! Ostream operator + friend std::ostream& operator<<( + std::ostream& os, //!< The ostream + const SingleElement& obj //!< The object + ); + +#endif + + public: + + // ---------------------------------------------------------------------- + // Member functions + // ---------------------------------------------------------------------- + + //! Serialization + Fw::SerializeStatus serialize( + Fw::SerializeBufferBase& buffer //!< The serial buffer + ) const; + + //! Deserialization + Fw::SerializeStatus deserialize( + Fw::SerializeBufferBase& buffer //!< The serial buffer + ); + +#if FW_ARRAY_TO_STRING || BUILD_UT + + //! Convert array to string + void toString( + Fw::StringBase& sb //!< The StringBase object to hold the result + ) const; + +#endif + + private: + + // ---------------------------------------------------------------------- + // Member variables + // ---------------------------------------------------------------------- + + //! The array elements + ElementType elements[SIZE]; + +}; + +#endif diff --git a/compiler/tools/fpp-to-cpp/test/array/run.sh b/compiler/tools/fpp-to-cpp/test/array/run.sh index 4fbb7fb4c..004ce88ea 100644 --- a/compiler/tools/fpp-to-cpp/test/array/run.sh +++ b/compiler/tools/fpp-to-cpp/test/array/run.sh @@ -64,3 +64,9 @@ header_path() run_test "-p $PWD" "include/T.fpp header_path" header_path && \ diff_cpp HeaderPathArray } + +single_element() +{ + run_test "-p $PWD" single_element && \ + diff_cpp SingleElementArray +} diff --git a/compiler/tools/fpp-to-cpp/test/array/single_element.fpp b/compiler/tools/fpp-to-cpp/test/array/single_element.fpp new file mode 100644 index 000000000..ac4625b82 --- /dev/null +++ b/compiler/tools/fpp-to-cpp/test/array/single_element.fpp @@ -0,0 +1,2 @@ +@ An array with one element +array SingleElement = [1] U32 diff --git a/compiler/tools/fpp-to-cpp/test/array/single_element.ref.txt b/compiler/tools/fpp-to-cpp/test/array/single_element.ref.txt new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/tools/fpp-to-cpp/test/array/tests.sh b/compiler/tools/fpp-to-cpp/test/array/tests.sh index 64e19df85..6f4512f9d 100644 --- a/compiler/tools/fpp-to-cpp/test/array/tests.sh +++ b/compiler/tools/fpp-to-cpp/test/array/tests.sh @@ -8,4 +8,5 @@ abs_type struct component header_path +single_element " diff --git a/compiler/tools/fpp-to-cpp/test/array/update-ref.sh b/compiler/tools/fpp-to-cpp/test/array/update-ref.sh index dcfae70f1..b55d1b703 100644 --- a/compiler/tools/fpp-to-cpp/test/array/update-ref.sh +++ b/compiler/tools/fpp-to-cpp/test/array/update-ref.sh @@ -64,3 +64,9 @@ header_path() update "-p $PWD" "include/T.fpp header_path" header_path move_cpp HeaderPathArray } + +single_element() +{ + update "-p $PWD" single_element + move_cpp SingleElementArray +}