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]; }Rien de bien folichon donc, mais ça oblige à créer autant de fonctions que de type de retour ...
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]; }
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 :
Et un exemple d'utilisation:
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; }
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
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);
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![]()
Partager