libfoedus-core
FOEDUS Core Library
endianness.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
18 #ifndef FOEDUS_ASSORTED_ENDIANNESS_HPP_
19 #define FOEDUS_ASSORTED_ENDIANNESS_HPP_
20 
21 #include <endian.h>
22 #include <stdint.h>
23 
24 #include <limits>
25 
26 #include "foedus/compiler.hpp"
27 
42 namespace foedus {
43 namespace assorted {
44 
53 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
54 const bool kIsLittleEndian = false;
55 #elif __BYTE_ORDER == __BIG_ENDIAN
56 const bool kIsLittleEndian = true;
57 #else // __BYTE_ORDER == __BIG_ENDIAN
58 #error "__BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN."
59 #endif // __BYTE_ORDER
60 
61 
62 // same as bswap, but this is standard, so let's prefer that.
63 // however, remember these are macros. we can't say "::be64toh"
64 template <typename T> T betoh(T be_value);
65 template <> inline uint64_t betoh<uint64_t>(uint64_t be_value) { return be64toh(be_value); }
66 template <> inline uint32_t betoh<uint32_t>(uint32_t be_value) { return be32toh(be_value); }
67 template <> inline uint16_t betoh<uint16_t>(uint16_t be_value) { return be16toh(be_value); }
68 template <> inline uint8_t betoh<uint8_t>(uint8_t be_value) { return be_value; }
69 
70 // the following is much simpler if we assume std::make_unsigned< I >, but that's C++11.
71 // we shouldn't use it in a public header.
72 // also, we shouldn't abuse template meta programming.
73 template <> inline int64_t betoh<int64_t>(int64_t be_value) {
74  return be64toh(static_cast<uint64_t>(be_value)) - (1ULL << 63);
75 }
76 template <> inline int32_t betoh<int32_t>(int32_t be_value) {
77  return be32toh(static_cast<uint32_t>(be_value)) - (1U << 31);
78 }
79 template <> inline int16_t betoh<int16_t>(int16_t be_value) {
80  return be16toh(static_cast<uint16_t>(be_value)) - (1U << 15);
81 }
82 template <> inline int8_t betoh<int8_t>(int8_t be_value) {
83  return be_value - (1U << 7);
84 }
85 
86 template <typename T> T htobe(T host_value);
87 template <> inline uint64_t htobe<uint64_t>(uint64_t host_value) { return htobe64(host_value); }
88 template <> inline uint32_t htobe<uint32_t>(uint32_t host_value) { return htobe32(host_value); }
89 template <> inline uint16_t htobe<uint16_t>(uint16_t host_value) { return htobe16(host_value); }
90 template <> inline uint8_t htobe<uint8_t>(uint8_t host_value) { return host_value; }
91 
92 template <> inline int64_t htobe<int64_t>(int64_t host_value) {
93  return htobe64(static_cast<uint64_t>(host_value) - (1ULL << 63));
94 }
95 template <> inline int32_t htobe<int32_t>(int32_t host_value) {
96  return htobe32(static_cast<uint32_t>(host_value) - (1U << 31));
97 }
98 template <> inline int16_t htobe<int16_t>(int16_t host_value) {
99  return htobe16(static_cast<uint16_t>(host_value) - (1U << 15));
100 }
101 template <> inline int8_t htobe<int8_t>(int8_t host_value) {
102  return host_value - (1U << 7);
103 }
104 
115 template <typename T>
116 inline T read_bigendian(const void* be_bytes) {
117  // all if clauses below will be elimiated by compiler.
118  const T* be_address = reinterpret_cast<const T*>(ASSUME_ALIGNED(be_bytes, sizeof(T)));
119  T be_value = *be_address;
120  return betoh(be_value);
121 }
122 
130 template <typename T>
131 inline void write_bigendian(T host_value, void* be_bytes) {
132  T* be_address = reinterpret_cast<T*>(ASSUME_ALIGNED(be_bytes, sizeof(T)));
133  *be_address = htobe<T>(host_value);
134 }
135 
136 } // namespace assorted
137 } // namespace foedus
138 
139 #endif // FOEDUS_ASSORTED_ENDIANNESS_HPP_
uint16_t betoh< uint16_t >(uint16_t be_value)
Definition: endianness.hpp:67
int64_t betoh< int64_t >(int64_t be_value)
Definition: endianness.hpp:73
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
int64_t htobe< int64_t >(int64_t host_value)
Definition: endianness.hpp:92
#define ASSUME_ALIGNED(x, y)
Wraps GCC's __builtin_assume_aligned.
Definition: compiler.hpp:111
int16_t betoh< int16_t >(int16_t be_value)
Definition: endianness.hpp:79
int8_t betoh< int8_t >(int8_t be_value)
Definition: endianness.hpp:82
int32_t htobe< int32_t >(int32_t host_value)
Definition: endianness.hpp:95
T htobe(T host_value)
uint64_t htobe< uint64_t >(uint64_t host_value)
Definition: endianness.hpp:87
void write_bigendian(T host_value, void *be_bytes)
Convert a native integer to big-endian bytes and write them to the given address. ...
Definition: endianness.hpp:131
uint8_t htobe< uint8_t >(uint8_t host_value)
Definition: endianness.hpp:90
T betoh(T be_value)
uint16_t htobe< uint16_t >(uint16_t host_value)
Definition: endianness.hpp:89
uint8_t betoh< uint8_t >(uint8_t be_value)
Definition: endianness.hpp:68
uint32_t betoh< uint32_t >(uint32_t be_value)
Definition: endianness.hpp:66
int8_t htobe< int8_t >(int8_t host_value)
Definition: endianness.hpp:101
uint64_t betoh< uint64_t >(uint64_t be_value)
Definition: endianness.hpp:65
T read_bigendian(const void *be_bytes)
Convert a big-endian byte array to a native integer.
Definition: endianness.hpp:116
uint32_t htobe< uint32_t >(uint32_t host_value)
Definition: endianness.hpp:88
int32_t betoh< int32_t >(int32_t be_value)
Definition: endianness.hpp:76
int16_t htobe< int16_t >(int16_t host_value)
Definition: endianness.hpp:98
const bool kIsLittleEndian
A handy const boolean to tell if it's little endina.
Definition: endianness.hpp:54