| 149 | } |
| 150 | |
| 151 | inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) { |
| 152 | // This is the "hottest" function (all offset lookups use this), so worth |
| 153 | // optimizing if possible. |
| 154 | // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a |
| 155 | // constant, which here it isn't. Test if memcpy is still faster than |
| 156 | // the conditionals in ReadSizedScalar. Can also use inline asm. |
| 157 | // clang-format off |
| 158 | #if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC) |
| 159 | // This is 64-bit Windows only, __movsb does not work on 32-bit Windows. |
| 160 | uint64_t u = 0; |
| 161 | __movsb(reinterpret_cast<uint8_t *>(&u), |
| 162 | reinterpret_cast<const uint8_t *>(data), byte_width); |
| 163 | return flatbuffers::EndianScalar(u); |
| 164 | #else |
| 165 | return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>( |
| 166 | data, byte_width); |
| 167 | #endif |
| 168 | // clang-format on |
| 169 | } |
| 170 | |
| 171 | inline double ReadDouble(const uint8_t *data, uint8_t byte_width) { |
| 172 | return ReadSizedScalar<double, quarter, half, float, double>(data, |