Bonjour à tous !

J'utilise depuis longtemps dans un de mes programme des fonctions permettant de lire le contenu d'un std::array de uint8_t. J'ai 3 fonctions génériques permettant de retourner soit un uint8_t, soit un uint16_t, soit un uint32_t.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
template<typename U, ::std::size_t N>
uint8_t RawRead8(const ::std::array<U, N> & arr, const ::std::uint32_t& adr)
{
    return arr[adr];
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
template<typename U, ::std::size_t N>
uint16_t RawRead16(const ::std::array<U, N> & arr, const ::std::uint32_t& adr)
{
    return arr[adr + 0] << 8 | arr[adr + 1];            
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
template<typename U, ::std::size_t N>
uint32_t RawRead32(const ::std::array<U, N> & arr, const ::std::uint32_t& adr)
{
    return arr[adr + 0] << 24 | arr[adr + 1] << 16 | arr[adr + 2] << 8 | arr[adr + 3];
}
Rien de bien folichon donc, mais ça oblige à créer autant de fonctions que de type de retour ...

J'ai donc voulu créer une unique fonction permettant de gérer autant de types que voulu (par ex retourner aussi un uint64_t).
Voici le résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
template<typename T, typename U, ::std::size_t N>
decltype(auto) RawRead(const ::std::array<U, N> & arr, const ::std::uint32_t& adr)
{
    T returnValue{};
    for (uint8_t i = 0; i <= sizeof(T) - 1; ++i) {
        returnValue <<= 8;
        returnValue |= arr[adr + i];
 
    }
    return returnValue;
}
Et un exemple d'utilisation:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
std::array <uint8_t, 0x100> memory;
memory[0] = 0xFE;
memory[1] = 0xDC;
memory[2] = 0xBA;
memory[3] = 0x98;
 
auto val32 = RawRead<uint32_t>(memory, 0x0);
Ce code fonctionne parfaitement. Mais lors de la vérification du code assembleur généré, je me rends compte que cette dernière fonction génère le code correspondant à la boucle, au lieu de faire une série de décalage à gauche comme la première fonction
Existe-t-il un moyen pour forcer le compilateur à dérouler la boucle ? Je ne suis pas assez calé en templates pour avoir la solution (je ne suis même pas sûr que ce soit faisable).

Merci de m'avoir lu