iceberg-cpp
Loading...
Searching...
No Matches
endian.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
22#include <bit>
23#include <concepts>
24#include <cstdint>
25#include <cstring>
26
29
30namespace iceberg {
31
33template <typename T>
34concept EndianConvertible = std::is_arithmetic_v<T>;
35
38template <EndianConvertible T>
39constexpr T ByteSwap(T value) {
40 if constexpr (sizeof(T) <= 1) {
41 return value;
42 } else if constexpr (std::is_integral_v<T>) {
43 return std::byteswap(value);
44 } else if constexpr (std::is_floating_point_v<T>) {
45 if constexpr (sizeof(T) == sizeof(uint16_t)) {
46 return std::bit_cast<T>(std::byteswap(std::bit_cast<uint16_t>(value)));
47 } else if constexpr (sizeof(T) == sizeof(uint32_t)) {
48 return std::bit_cast<T>(std::byteswap(std::bit_cast<uint32_t>(value)));
49 } else if constexpr (sizeof(T) == sizeof(uint64_t)) {
50 return std::bit_cast<T>(std::byteswap(std::bit_cast<uint64_t>(value)));
51 } else {
52 static_assert(sizeof(T) == 0,
53 "Unsupported floating-point size for endian conversion.");
54 }
55 }
56}
57
59template <EndianConvertible T>
60constexpr T ToLittleEndian(T value) {
61 if constexpr (std::endian::native == std::endian::little) {
62 return value;
63 } else {
64 return ByteSwap(value);
65 }
66}
67
69template <EndianConvertible T>
70constexpr T FromLittleEndian(T value) {
71 if constexpr (std::endian::native == std::endian::little) {
72 return value;
73 } else {
74 return ByteSwap(value);
75 }
76}
77
79template <EndianConvertible T>
80constexpr T ToBigEndian(T value) {
81 if constexpr (std::endian::native == std::endian::big) {
82 return value;
83 } else {
84 return ByteSwap(value);
85 }
86}
87
89template <EndianConvertible T>
90constexpr T FromBigEndian(T value) {
91 if constexpr (std::endian::native == std::endian::big) {
92 return value;
93 } else {
94 return ByteSwap(value);
95 }
96}
97
100template <EndianConvertible T>
101void WriteLittleEndian(T value, void* output) {
102 auto le = ToLittleEndian(value);
103 std::memcpy(output, &le, sizeof(le));
104}
105
108template <EndianConvertible T>
109T ReadLittleEndian(const void* input) {
110 T value;
111 std::memcpy(&value, input, sizeof(value));
112 return FromLittleEndian(value);
113}
114
115} // namespace iceberg
Concept for values that can be converted to/from another endian format.
Definition endian.h:34
constexpr T ToLittleEndian(T value)
Convert a value to little-endian format.
Definition endian.h:60
constexpr T FromLittleEndian(T value)
Convert a value from little-endian format.
Definition endian.h:70
constexpr T ByteSwap(T value)
Byte-swap a value. For floating-point types, only support 32-bit and 64-bit floats.
Definition endian.h:39
constexpr T ToBigEndian(T value)
Convert a value to big-endian format.
Definition endian.h:80
constexpr T FromBigEndian(T value)
Convert a value from big-endian format.
Definition endian.h:90