Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
endian_traits.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * Multiscale Universal Interface Code Coupling Library *
3 * *
4 * Copyright (C) 2019 Y. H. Tang, S. Kudo, X. Bian, Z. Li, G. E. Karniadakis, *
5 * R. W. Nash *
6 * *
7 * (* The University of Edinburgh) *
8 * *
9 * This software is jointly licensed under the Apache License, Version 2.0 *
10 * and the GNU General Public License version 3, you may use it according *
11 * to either. *
12 * *
13 * ** Apache License, version 2.0 ** *
14 * *
15 * Licensed under the Apache License, Version 2.0 (the "License"); *
16 * you may not use this file except in compliance with the License. *
17 * You may obtain a copy of the License at *
18 * *
19 * http://www.apache.org/licenses/LICENSE-2.0 *
20 * *
21 * Unless required by applicable law or agreed to in writing, software *
22 * distributed under the License is distributed on an "AS IS" BASIS, *
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
24 * See the License for the specific language governing permissions and *
25 * limitations under the License. *
26 * *
27 * ** GNU General Public License, version 3 ** *
28 * *
29 * This program is free software: you can redistribute it and/or modify *
30 * it under the terms of the GNU General Public License as published by *
31 * the Free Software Foundation, either version 3 of the License, or *
32 * (at your option) any later version. *
33 * *
34 * This program is distributed in the hope that it will be useful, *
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
37 * GNU General Public License for more details. *
38 * *
39 * You should have received a copy of the GNU General Public License *
40 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
41 *****************************************************************************/
42 
75 #ifndef MUI_ENDIAN_TRAITS_H_
76 #define MUI_ENDIAN_TRAITS_H_
77 
78 #include <cstdint>
79 
80 #ifdef __APPLE__
81 // Provide mappings to Apple specific function/macros
82 # include <machine/endian.h>
83 # include <libkern/OSByteOrder.h>
84 
85 # define htobe16(x) OSSwapHostToBigInt16(x)
86 # define htole16(x) OSSwapHostToLittleInt16(x)
87 # define be16toh(x) OSSwapBigToHostInt16(x)
88 # define le16toh(x) OSSwapLittleToHostInt16(x)
89 
90 # define htobe32(x) OSSwapHostToBigInt32(x)
91 # define htole32(x) OSSwapHostToLittleInt32(x)
92 # define be32toh(x) OSSwapBigToHostInt32(x)
93 # define le32toh(x) OSSwapLittleToHostInt32(x)
94 
95 # define htobe64(x) OSSwapHostToBigInt64(x)
96 # define htole64(x) OSSwapHostToLittleInt64(x)
97 # define be64toh(x) OSSwapBigToHostInt64(x)
98 # define le64toh(x) OSSwapLittleToHostInt64(x)
99 #else
100 # include <endian.h>
101 #endif
102 
103 # define MUI_POSITIVE true
104 # define MUI_NEGATIVE false
105 
106 // Convert input definitions (see above) to two macros returning bool
107 // (MUI_CONVERT_FLOAT & MUI_CONVERT_INT) that tell the implementation
108 // what to do
109 #ifdef MUI_IGNORE_ENDIAN
110 // Sanity check
111 # if defined(MUI_INT_BIG_ENDIAN) || defined(MUI_INT_LITTLE_ENDIAN) || defined(MUI_FLOAT_BIG_ENDIAN) || defined(MUI_FLOAT_LITTLE_ENDIAN)
112 # error "MUI Error [endian_traits.h]: Must set no other MUI endian options with MUI_IGNORE_ENDIAN"
113 # endif
114 
115 // Never convert
116 # define MUI_CONVERT_INT false
117 # define MUI_CONVERT_FLOAT false
118 
119 #else // Not ignoring
120 
121 // Integer
122 # ifdef MUI_INT_BIG_ENDIAN
123 # ifdef MUI_INT_LITTLE_ENDIAN
124 # error "MUI Error [endian_traits.h]: Both MUI_INT_BIG_ENDIAN and MUI_INT_LITTLE_ENDIAN defined"
125 # else
126 # define MUI_INT_DEFINED MUI_POSITIVE
127 # define MUI_CONVERT_INT false
128 # endif
129 # else
130 # ifdef MUI_INT_LITTLE_ENDIAN
131 # define MUI_INT_DEFINED MUI_POSITIVE
132 # define MUI_CONVERT_INT true
133 # else
134 // We have no endian options - try to figure it out.
135 # if defined(__BYTE_ORDER__)
136 # define MUI_INT_DEFINED MUI_POSITIVE
137 # define MUI_CONVERT_INT (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)
138 # else
139 # define MUI_INT_DEFINED MUI_NEGATIVE
140 # error "MUI Error [endian_traits.h]: Cannot auto-detect integer endianness of platform - please set at compilation (-DMUI_INT_LITTLE_ENDIAN or -DMUI_INT_BIG_ENDIAN) or set to ignore (-DMUI_IGNORE_ENDIAN)"
141 # endif
142 # endif
143 # endif
144 
145 // Floating point
146 # ifdef MUI_FLOAT_BIG_ENDIAN
147 # ifdef MUI_FLOAT_LITTLE_ENDIAN
148 # error "MUI Error [endian_traits.h]: Both MUI_FLOAT_BIG_ENDIAN and MUI_FLOAT_LITTLE_ENDIAN defined"
149 # else
150 # define MUI_CONVERT_FLOAT false
151 # endif
152 # else
153 # ifdef MUI_FLOAT_LITTLE_ENDIAN
154 # define MUI_CONVERT_FLOAT true
155 # else
156 // We have no endian options - try to figure it out.
157 # if defined(__FLOAT_WORD_ORDER__)
158 # define MUI_CONVERT_FLOAT (__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__)
159 # else // Likely using something other than GNU
160 # if MUI_INT_DEFINED == MUI_POSITIVE
161 # define MUI_CONVERT_FLOAT MUI_CONVERT_INT
162 # warning "MUI Warning [endian_traits.h]: Cannot auto-detect float endianness of platform - please set at compilation (-DMUI_FLOAT_LITTLE_ENDIAN or -DMUI_FLOAT_BIG_ENDIAN) or set to ignore (-DMUI_IGNORE_ENDIAN), integer endianness will be followed by default"
163 # else
164 # error "MUI Error [endian_traits.h]: Cannot auto-detect float endianness of platform - please set at compilation (-DMUI_FLOAT_LITTLE_ENDIAN or -DMUI_FLOAT_BIG_ENDIAN) or set to ignore (-DMUI_IGNORE_ENDIAN)"
165 # endif
166 # endif
167 # endif
168 # endif
169 
170 #endif // End definition processing
171 
172 namespace mui {
173 
174  namespace detail {
175  // Metafunction to get an unsigned integer type of the specified
176  // size in bytes as member type named "type".
177  template<size_t size_bytes>
178  struct uint;
179  // Specialisations for 8, 16, 32, 64 bits
180  template<>
181  struct uint<1> {
182  using type = uint8_t;
183  };
184  template<>
185  struct uint<2> {
186  using type = uint16_t;
187  };
188  template<>
189  struct uint<4> {
190  using type = uint32_t;
191  };
192  template<>
193  struct uint<8> {
194  using type = uint64_t;
195  };
196  // Helper class to convert betweem host and big-endian
197  // (i.e. network) ordering using the htobe/betoh family of
198  // functions.
199  template<size_t size_bytes>
201  union data_t {
202  char buf[size_bytes];
204  };
206  void htobe();
207  void betoh();
208  };
209  // Specialisations
210  template<>
212  data.val = htobe16(data.val);
213  }
214  template<>
216  data.val = be16toh(data.val);
217  }
218  template<>
220  data.val = htobe32(data.val);
221  }
222  template<>
224  data.val = be32toh(data.val);
225  }
226  template<>
228  data.val = htobe64(data.val);
229  }
230  template<>
232  data.val = be64toh(data.val);
233  }
234  }
235 
236  // Traits class for controlling MUI's behaviour about endianness.
237  //
238  // Uses SFINAE to select the appropriate specialisation based on the
239  // type.
240  //
241  // It defines a bool constexpr member "convert" that indicates if
242  // the type should undergo byte reordering as it is (de-)serialised.
243  //
244  // Currently will handle integral (signed or unsigned, widths of 8,
245  // 16, 32, 64 b) and floating (32 or 64 b) types.
246  template<typename T, typename enable = void>
248 
249  // Integers
250  template<typename T>
251  struct endian_traits<T, typename std::enable_if<std::is_integral<T>::value>::type>
252  {
253  static constexpr bool convert = (sizeof(T) > 1) && MUI_CONVERT_INT;
254  };
255 
256  // Floats
257  template<typename T>
258  struct endian_traits<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
259  {
260  static constexpr bool convert = MUI_CONVERT_FLOAT;
261  };
262 
263 }
264 
265 #endif // Include guard
#define MUI_CONVERT_FLOAT
Definition: endian_traits.h:161
T
Definition: dim.h:363
Definition: comm.h:54
Definition: endian_traits.h:200
data_t data
Definition: endian_traits.h:205
uint8_t type
Definition: endian_traits.h:182
uint16_t type
Definition: endian_traits.h:186
uint32_t type
Definition: endian_traits.h:190
uint64_t type
Definition: endian_traits.h:194
Definition: endian_traits.h:178
Definition: endian_traits.h:247
Definition: endian_traits.h:201
char buf[size_bytes]
Definition: endian_traits.h:202
uint< size_bytes >::type val
Definition: endian_traits.h:203