both signed and unsigned as function parameter

Viewed 96

I have functions to read data from an EEPROM. When I want to read a short, regardless of it being signed or unsigned, I know I have to read 2 bytes. Same principle goes when I want to read an integer: I have to read 4 bytes, regardless of it being signed or unsigned.

Thus I wrote 4 functions: one that reads a short, one that reads an unsigned short, one that reads an int, one that reads an unsigned int, etc.

Usage looks like this :

// define a default value at zero
uint16_t API_PORT = 0;

// retrieve the API port, that would be between 0 to 65535, saved on the EEPROM
i2cReadUnsignedShortFromExternalEEPROM(I2C_ADDR_EEPROM, 12345, &API_PORT);

// the function
void i2cReadUnsignedShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAdress, uint16_t *number) {
  byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress);
  byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress + 1);

  *number = (firstByte << 8) + secondByte;
}

The function to read a SIGNED short is almost exactly the same, except the third parameter :

void i2cReadShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAdress, short *number) {
  byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress);
  byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress + 1);

  *number = (firstByte << 8) + secondByte;
}

Eventhough everything works fine, it bothers me as it introduces a lot of redundancy in my code.

Is there a way to refactor those two similar functions into just one? The function would need to work in both following pseudocode scenarios :

unsigned short myUnsignedVar = 0;
myNewMethod(I2C_ADDR_EEPROM, 10, &myUnsignedVar);
// myUnsignedVar now holds value of 65000

signed short mySignedVar = 0;
myNewMethod(I2C_ADDR_EEPROM, 12, &mySignedVar);
// mySignedVar now holds value of -123

In other words, I want to make it so that the function accepts both signed and unsigned as 3rd parameter. I'm new to C++

1 Answers

Following @Taekahn 's comment regarding function templates, my function now looks like this :

template <typename T>
void i2cReadShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAddress, T *number) {
  byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAddress);
  byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAddress + 1);

  *number = (firstByte << 8) + secondByte;
}

It seems to work fine (tested).

Example of usage :

i2cReadShortFromExternalEEPROM<uint16_t>(I2C_ADDR_EEPROM, some_page, &API_PORT); // 443

i2cReadShortFromExternalEEPROM<short>(I2C_ADDR_EEPROM, some_page, &DEPTH); // -12345

Thank you for your guidance.

Related