15 #ifndef DDSTRUCTURE_H_INCLUDED
16 #define DDSTRUCTURE_H_INCLUDED
22 #include <type_traits>
106 const uint32_t struct_version = 1,
108 const std::string& comment = {},
109 const dd::Version& ddl_version = {});
123 const std::string& xml_string,
143 size_t array_size = 1);
184 size_t array_size = 1);
227 template <
typename PREDEF_DATA_TYPE>
229 size_t array_size = 1,
230 const std::string& special_type_name = {})
232 if (special_type_name.empty()) {
236 addElement(element_name, DataType<PREDEF_DATA_TYPE>(special_type_name), array_size);
261 template <
typename PREDEF_DATA_TYPE>
265 const std::string& special_type_name = {})
267 if (special_type_name.empty()) {
272 element_name, DataType<PREDEF_DATA_TYPE>(special_type_name), array_size, alignment);
296 const std::string& constant_value = {});
319 const std::string& constant_value = {});
338 const std::string& constant_value = {});
361 size_t array_size = 1);
431 return _struct_type->getElements().cbegin();
440 return _struct_type->getElements().cend();
449 return _struct_type->getElements().begin();
458 return _struct_type->getElements().end();
541 const std::string& description = {},
542 const std::string& comment = {},
543 const std::string& value = {},
544 const std::string& minimum_value = {},
545 const std::string& maximum_value = {},
546 const std::string& default_value = {},
547 const std::string& scale = {},
548 const std::string& offset = {});
573 template <
typename T,
bool align_with_padding>
576 void popLastElement();
579 std::shared_ptr<dd::StructType> _struct_type;
586 template <
typename T,
typename Enable =
void>
588 static constexpr
size_t value = 1;
591 template <
typename T>
592 struct arrayCount<T, typename std::enable_if<std::is_array<T>::value>::type> {
593 static constexpr
size_t value =
594 sizeof(T) /
sizeof(
typename std::remove_pointer<
typename std::decay<T>::type>::type);
597 template <
typename T,
typename MemberType>
598 size_t memberPointerToOffset(MemberType T::*member)
601 return reinterpret_cast<size_t>(&(start->*member));
643 template <
typename T,
bool align_with_padding = true>
645 static_assert(std::is_trivially_copyable<T>::value,
646 "You can only use structs with plain old datatypes and complex members. Do not "
657 : _structure(name, struct_version, alignof(T))
666 template <
typename MemberType>
671 .
addElement<
typename std::remove_pointer<typename std::decay<MemberType>::type>::type>(
673 detail::arrayCount<MemberType>::value,
675 name, detail::memberPointerToOffset(member_offset),
alignof(MemberType)));
687 template <
typename MemberType>
689 MemberType T::*member_offset,
695 detail::arrayCount<MemberType>::value,
696 *evaluateAlignment(name,
697 detail::memberPointerToOffset(member_offset),
698 alignof(MemberType)));
709 template <
typename MemberType>
711 MemberType T::*member_offset,
717 detail::arrayCount<MemberType>::value,
718 *evaluateAlignment(name,
719 detail::memberPointerToOffset(member_offset),
720 alignof(MemberType)));
755 return _structure.
getDD();
825 const std::string& description = {},
826 const std::string& comment = {},
827 const std::string& value = {},
828 const std::string& minimum_value = {},
829 const std::string& maximum_value = {},
830 const std::string& default_value = {},
831 const std::string& scale = {},
832 const std::string& offset = {})
876 if (align_with_padding) {
877 auto current_struct_size = _structure.
getSize();
878 if (
sizeof(T) > current_struct_size) {
880 "__padding_final",
sizeof(T) - current_struct_size, 1);
881 _padded_final =
true;
887 if (align_with_padding) {
889 _structure.popLastElement();
890 _padded_final =
false;
894 void validate()
const
896 constexpr
auto padding_aligned = align_with_padding;
897 if (!padding_aligned) {
898 if (_structure.
getSize() !=
sizeof(T)) {
900 "DDStructureGenerator::validate",
902 "' does not have the expected size of (" +
std::to_string(
sizeof(T)) +
904 "). Check if there are missed or misordered elements. ");
910 size_t member_offset,
911 size_t member_type_alignment)
917 if (member_offset < current_struct_offset) {
921 "The evaluated struct size of '" +
getStructName() +
"' is already (" +
922 std::to_string(current_struct_offset) +
") - Trying to add a member at (" +
924 ") at a address prior the last element. Check misordered addElement calls.");
928 auto difference = member_offset - current_struct_offset;
932 size_t minimum_alignment = member_type_alignment;
933 if (member_type_alignment >
alignof(T)) {
934 minimum_alignment =
alignof(T);
937 auto valid_alignment_range = {1u, 2u, 4u, 8u, 16u, 32u, 64u};
940 for (
size_t alignment: valid_alignment_range) {
942 if (alignment <=
alignof(T)) {
943 if (alignment >= minimum_alignment) {
944 if (alignment > difference && member_offset % alignment == 0) {
957 if (difference < minimum_alignment) {
958 for (
size_t alignment: valid_alignment_range) {
959 if (alignment < minimum_alignment) {
960 if (alignment > difference && member_offset % alignment == 0) {
973 if (align_with_padding) {
974 if (difference != 0) {
975 _structure.
addElement<uint8_t>(
"__padding_" + element_name, difference, 1);
985 "' it is not possible to find a valid member alignment to reach offset (" +
990 DDStructure _structure;
991 bool _padded_final =
false;
A DataType class holding the DD for a Datatype with dependencies.
Utility class for a complete valid data definition of one StructType::Element and its dependencies.
Utility class for a complete valid data definition of one EnumType and its dependencies.
Creating a valid Structure Data Definition by a existing type and its member types.
std::string getStructName() const
Gets the Struct Name.
std::string getStructDescription() const
Gets the Struct Data Description as XML String.
const dd::DataDefinition & getDD() const
returns a valid DDL.
DDStructureGenerator & addElement(const std::string &name, MemberType T::*member_offset, const DDEnum &enum_type)
Adds a new member of an enumeration type by member reference pointer.
DDStructureGenerator & addElement(const std::string &name, MemberType T::*member_offset)
Adds a new member of data type (POD) by member reference pointer.
DDStructureGenerator(const std::string &name, uint32_t struct_version=1)
CTOR to create a structure type based on a type.
void setElementUnit(const std::string &element_name, const dd::BaseUnit &base_unit)
Sets additional element base unit information to the given element_name.
const dd::StructType & getStructType() const
Get the Struct Type object.
size_t getAlignment() const
Retrieves the current evaluated alignment of the structure.
size_t getSize() const
Retrieves the current evaluated size of the structure.
void setStructInfo(const std::string &comment)
Set additional struct information like comment.
void setElementUnit(const std::string &element_name, const DDUnit &unit)
Sets additional element unit information to the given element_name.
const DDStructure & getStructure() const
Get the current valid DDStructure object.
DDStructureGenerator & addElement(const std::string &name, MemberType T::*member_offset, const DDStructure &struct_type)
Adds a new member of an structure type by member reference pointer.
void setElementInfo(const std::string &element_name, const std::string &description={}, const std::string &comment={}, const std::string &value={}, const std::string &minimum_value={}, const std::string &maximum_value={}, const std::string &default_value={}, const std::string &scale={}, const std::string &offset={})
Set additional element information to the given element_name.
Utility class for a complete valid data definition of one StructType and its dependencies.
std::string getStructName() const
Gets the Struct Name.
DDStructure(const DDStructure &other)
Construct a new DDStructure object.
DDStructure & addElement(const std::string &element_name, const dd::DataType &data_type, size_t array_size, size_t alignment)
Adds one element to the struct using a (POD) DataType.
std::string getStructDescription() const
Gets the Struct Data Description as XML String.
const_iterator begin() const
returns the first elenents iterator for range based iterations.
DDStructure & addElement(const std::string &element_name, const DDDataType &data_type, size_t array_size=1)
Adds one element to the struct using a (POD) DataType.
~DDStructure()=default
Destroy the DDStructure object.
bool isCompatible(const DDStructure &other) const
binary compares the structs
DDStructure & addElement(const std::string &element_name, const DDStructure &struct_type, size_t array_size=1)
Adds one element to the struct using the convenience class DDStructure.
const_iterator cbegin() const
returns the first elements iterator.
const dd::DataDefinition & getDD() const
returns a valid DDL.
DDStructure & addElement(const DDElement &element)
Adds one element to the struct using the convenience class DDElement.
dd::datamodel::StructType::Elements::const_iterator const_iterator
iterator to iterate the elements of the struct
DDStructure(const std::string &name, const uint32_t struct_version=1, dd::OptionalSize alignment={}, const std::string &comment={}, const dd::Version &ddl_version={})
Construct a new DDStructure object.
void setElementUnit(const std::string &element_name, const dd::BaseUnit &base_unit)
Sets additional element base unit information to the given element_name.
DDStructure & addElement(const std::string &element_name, const DDEnum &enum_type, const std::string &constant_value={})
Adds one element to the struct using the convenience class DDEnum.
const dd::StructType & getStructType() const
Get the Struct Type object.
DDStructure(const std::string &name, const std::string &xml_string, const dd::Version &ddl_xml_file_version_to_parse=dd::Version(0, 0))
Construct a new DDStructure object.
DDStructure()=delete
Construct a new DDStructure object.
size_t getAlignment() const
Retrieves the current evaluated alignment of the structure.
DDStructure & addElement(const std::string &element_name, size_t array_size=1, const std::string &special_type_name={})
Adds one element to the struct using a (POD) DataType.
DDStructure & addElement(const std::string &element_name, size_t array_size, size_t alignment, const std::string &special_type_name={})
Adds one element to the struct using a (POD) DataType.
const_iterator cend() const
returns the end elements iterator.
DDStructure & addElement(const std::string &element_name, const dd::DataType &data_type, size_t array_size=1)
Adds one element to the struct using a (POD) DataType.
DDStructure & addElement(const std::string &element_name, const DDDataType &data_type, size_t array_size, size_t alignment)
Adds one element to the struct using a (POD) DataType.
size_t getSize() const
Retrieves the current evaluated deserialized size (in bytes) of the structure.
DDStructure & addElements(const std::vector< DDElement > &elements)
Adds a list of element to the struct using the convenience class DDElement.
void setStructInfo(const std::string &comment)
Set additional struct information like comment.
void setElementUnit(const std::string &element_name, const DDUnit &unit)
Sets additional element unit information to the given element_name.
DDStructure & operator=(const DDStructure &other)
copy assignment operator
const_iterator end() const
returns the end elements iterator.
DDStructure & addElement(const std::string &element_name, const DDEnum &enum_type, size_t array_size, const std::string &constant_value={})
Adds one element to the struct using the convenience class DDEnum.
DDStructure & operator=(DDStructure &&other)
move assignment operator
DDStructure & addElement(const std::string &element_name, const DDStructure &struct_type, size_t array_size, size_t alignment)
Adds one element to the struct using the convenience class DDStructure.
void setElementInfo(const std::string &element_name, const std::string &description={}, const std::string &comment={}, const std::string &value={}, const std::string &minimum_value={}, const std::string &maximum_value={}, const std::string &default_value={}, const std::string &scale={}, const std::string &offset={})
Set additional element information to the given element_name.
bool isEqual(const DDStructure &other) const
equal in names and descriptions
DDStructure(DDStructure &&other)
Construct a new DDStructure object.
DDStructure & addElement(const std::string &element_name, const DDEnum &enum_type, size_t array_size, size_t alignment, const std::string &constant_value={})
Adds one element to the struct using the convenience class DDEnum.
The unit class holding a reference to its complete DD (references to baseunits and prefixes)
Generator template to create DataType for the plain c-types.
The Data Definiton class uses the validation model to keep a Data Definition datamodel (ddl::dd::data...
StructTypeAccess getStructTypeAccess(const std::string &type_name) const
Get the Struct Type Access, where to enter the type and calculated element position information.
size_t getStaticUnalignedStructSize() const
Get the known unaligned Static Struct Size of this instance (this is usually the last position + size...
observable DataDefinition object class to describe (POD) DataType.
observable DataDefinition object class to describe StructType.
container_type::const_iterator const_iterator
local definition of the container const_iterator
OO DataDefinition - Data Definition.
OO DataDefinition Element Header.
@ enum_type
value for enum type
@ data_type
value for data type
@ struct_type
value for struct type
cString to_string(const tResult &i_oResult, eResultFormatFlags i_eFormatFlags=eResultFormatFlags::RFF_DisableNone, const tChar *i_strFormat=nullptr)
Copy all information of an assigned result object to a (formatted) string.
Error
Enumerates possible error values for filesystem interaction.
@ unit
the unit is a unit (Unit)
@ base_unit
the unit is a base unit (BaseUnit)
utility::Optional< size_t > OptionalSize
Optional Size Type.
definition of the ddl namespace
Utility for the Neutrino gcc5 compiler which has really no std::to_string implementation!