#pragma once #include #include #include #include #include namespace pldm { namespace bios { namespace utils { using Table = std::vector; /** @class BIOSTableIter * @brief Const Iterator of a BIOS Table */ template class BIOSTableIter { public: /** @struct EndSentinel * @brief Auxiliary struct to delimit a range */ struct EndSentinel {}; /** @struct iterator * @brief iterator owns the BIOS table */ class iterator { public: /** @brief Get entry type by specifying \p tableType */ using T = typename std::conditional< tableType == PLDM_BIOS_STRING_TABLE, pldm_bios_string_table_entry, typename std::conditional< tableType == PLDM_BIOS_ATTR_TABLE, pldm_bios_attr_table_entry, typename std::conditional::type>::type>::type; static_assert(!std::is_void::value); /** @brief Constructors iterator * * @param[in] data - Pointer to a table * @param[in] length - The length of the table */ explicit iterator(const void* data, size_t length) : iter(pldm_bios_table_iter_create(data, length, tableType), pldm_bios_table_iter_free) { if (!iter) { throw std::runtime_error( "Unable to create bios table iterator"); } } /** @brief Get the entry pointed by the iterator * * @return Pointer to the entry */ const T* operator*() const { return reinterpret_cast( pldm_bios_table_iter_value(iter.get())); } /** @brief Make the iterator point to the next entry * * @return The iterator itself */ iterator& operator++() { pldm_bios_table_iter_next(iter.get()); return *this; } /** @brief Check if the iterator ends * * @return True if the iterator ends */ bool operator==(const EndSentinel&) const { return pldm_bios_table_iter_is_end(iter.get()); } /** @brief Check if the iterator ends * * @return False if the iterator ends */ bool operator!=(const EndSentinel& endSentinel) const { return !operator==(endSentinel); } private: std::unique_ptr iter; }; /** @brief Constructors BIOSTableIterator * * @param[in] data - Pointer to a table * @param[in] length - The length of the table */ BIOSTableIter(const void* data, size_t length) noexcept : tableData(data), tableSize(length) {} /** @brief Get the iterator to the beginning * * @return An iterator to the beginning */ iterator begin() { return iterator(tableData, tableSize); } /** @brief Get the iterator to the end * * @return An iterator to the end */ EndSentinel end() { return {}; } private: const void* tableData; size_t tableSize; }; } // namespace utils } // namespace bios } // namespace pldm