如何编写constexpr交换函数来改变整数的字节序? [英] How to write constexpr swap function to change endianess of an integer?

查看:119
本文介绍了如何编写constexpr交换函数来改变整数的字节序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何编写 constexpr 函数来交换整数的字节序,而不需要依赖编译器扩展,你能给出一个如何做的例子吗?

How to write a constexpr function to swap endianess of an integer, without relying on compiler extensions and can you give an example on how to do it?

推荐答案

是的,这很容易;这里是一个递归(C ++ 11兼容)实现(仅限无符号整数类型):

Yes, it's pretty easy; here's a recursive (C++11-compatible) implementation (unsigned integral types only):

#include <climits>
#include <cstdint>
#include <type_traits>

template<class T>
constexpr typename std::enable_if<std::is_unsigned<T>::value, T>::type
bswap(T i, T j = 0u, std::size_t n = 0u) {
  return n == sizeof(T) ? j :
    bswap<T>(i >> CHAR_BIT, (j << CHAR_BIT) | (i & (T)(unsigned char)(-1)), n + 1);
}

示例

c $ c> j 作为累加器, n 作为循环计数器(索引字节)。

Here I'm using j as the accumulator and n as the loop counter (indexing bytes).

如果您有支持 C ++ 17次表达式的编译器,则可以写一些东西

If you have a compiler supporting C++17 fold expressions, it's possible to write something that expands out into exactly what you'd write by hand:

template<class T, std::size_t... N>
constexpr T bswap_impl(T i, std::index_sequence<N...>) {
  return ((((i >> (N * CHAR_BIT)) & (T)(unsigned char)(-1)) <<
           ((sizeof(T) - 1 - N) * CHAR_BIT)) | ...);
}; //                                        ^~~~~ fold expression
template<class T, class U = typename std::make_unsigned<T>::type>
constexpr U bswap(T i) {
  return bswap_impl<U>(i, std::make_index_sequence<sizeof(T)>{});
}

此表单的优点是因为它不使用循环或递归,你几乎可以得到最佳的汇编输出 - 在x86-64,clang甚至管理使用 bswap 指令

The advantage of this form is that because it doesn't use loops or recursion, you're pretty much guaranteed to get optimal assembly output - on x86-64, clang even manages to work out to use the bswap instruction.

这篇关于如何编写constexpr交换函数来改变整数的字节序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆