speeduino/speeduino/table3d_axes.h

121 lines
3.1 KiB
C++

/**
* @addtogroup table_3d
* @{
*/
/** \file
* @brief 3D table axis types and iterators
*/
#pragma once
#include "table3d_typedefs.h"
/**\enum axis_domain
* @brief Encodes the real world measurement that a table axis captures
* */
enum axis_domain {
/** RPM (engine speed) */
axis_domain_Rpm,
/** Load */
axis_domain_Load,
/** Throttle position */
axis_domain_Tps
};
/** @brief Iterate over table axis elements */
class table_axis_iterator
{
public:
/** @brief Construct */
table_axis_iterator(table3d_axis_t *pStart, const table3d_axis_t *pEnd, axis_domain domain)
: _stride(pEnd>pStart ? stride_inc : stride_dec)
, _pStart(pStart)
, _pEnd(pEnd + _stride)
, _domain(domain) //cppcheck-suppress misra-c2012-10.4
{
}
axis_domain get_domain(void) const { return _domain; }
/** @brief Advance the iterator
* @param steps The number of elements to move the iterator
*/
table_axis_iterator& advance(int8_t steps)
{
_pStart = _pStart + ((int16_t)_stride * steps);
return *this;
}
/** @brief Increment the iterator by one element*/
table_axis_iterator& operator++(void)
{
return advance(1);
}
/** @brief Test for end of iteration */
bool at_end(void) const
{
return _pStart == _pEnd;
}
/** @brief Dereference the iterator */
table3d_axis_t& operator*(void)
{
return *_pStart;
}
/** @copydoc table_axis_iterator::operator*() */
const table3d_axis_t& operator*(void) const
{
return *_pStart;
}
private:
static constexpr int8_t stride_inc = 1;
static constexpr int8_t stride_dec = -1;
int8_t _stride;
table3d_axis_t *_pStart;
const table3d_axis_t *_pEnd;
const axis_domain _domain;
};
#define TABLE3D_TYPENAME_AXIS(size, domain) table3d ## size ## domain ## _axis
#define TABLE3D_GEN_AXIS(size, dom) \
/** @brief The dxis for a 3D table with size x size dimensions and domain 'domain' */ \
struct TABLE3D_TYPENAME_AXIS(size, dom) { \
/** @brief The length of the axis in elements */ \
static constexpr table3d_dim_t length = (size); \
/** @brief The domain the axis represents */ \
static constexpr axis_domain domain = axis_domain_ ## dom; \
/**
@brief The axis elements\
*/ \
table3d_axis_t axis[(size)]; \
\
/** @brief Iterate over the axis elements */ \
table_axis_iterator begin(void) \
{ \
return table_axis_iterator(axis+(size)-1, axis, domain); \
} \
/** @brief Iterate over the axis elements, from largest to smallest */ \
table_axis_iterator rbegin(void) \
{ \
return table_axis_iterator(axis, axis+(size)-1, domain); \
} \
};
// This generates the axis types for the following sizes & domains:
TABLE3D_GEN_AXIS(6, Rpm)
TABLE3D_GEN_AXIS(6, Load)
TABLE3D_GEN_AXIS(4, Rpm)
TABLE3D_GEN_AXIS(4, Load)
TABLE3D_GEN_AXIS(8, Rpm)
TABLE3D_GEN_AXIS(8, Load)
TABLE3D_GEN_AXIS(8, Tps)
TABLE3D_GEN_AXIS(16, Rpm)
TABLE3D_GEN_AXIS(16, Load)
/** @} */