]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // boost/endian/conversion.hpp -------------------------------------------------------// |
2 | ||
3 | // Copyright Beman Dawes 2010, 2011, 2014 | |
4 | ||
5 | // Distributed under the Boost Software License, Version 1.0. | |
6 | // http://www.boost.org/LICENSE_1_0.txt | |
7 | ||
8 | #ifndef BOOST_ENDIAN_CONVERSION_HPP | |
9 | #define BOOST_ENDIAN_CONVERSION_HPP | |
10 | ||
11 | #include <boost/config.hpp> | |
12 | #include <boost/predef/detail/endian_compat.h> | |
13 | #include <boost/cstdint.hpp> | |
14 | #include <boost/endian/detail/intrinsic.hpp> | |
15 | #include <boost/core/scoped_enum.hpp> | |
16 | #include <boost/static_assert.hpp> | |
17 | #include <algorithm> | |
18 | #include <cstring> // for memcpy | |
19 | ||
20 | //------------------------------------- synopsis ---------------------------------------// | |
21 | ||
22 | namespace boost | |
23 | { | |
24 | namespace endian | |
25 | { | |
26 | BOOST_SCOPED_ENUM_START(order) | |
27 | { | |
28 | big, little, | |
29 | # ifdef BOOST_BIG_ENDIAN | |
30 | native = big | |
31 | # else | |
32 | native = little | |
33 | # endif | |
34 | }; BOOST_SCOPED_ENUM_END | |
35 | ||
36 | //--------------------------------------------------------------------------------------// | |
37 | // // | |
38 | // return-by-value interfaces // | |
39 | // suggested by Phil Endecott // | |
40 | // // | |
41 | // user-defined types (UDTs) // | |
42 | // // | |
43 | // All return-by-value conversion function templates are required to be implemented in // | |
44 | // terms of an unqualified call to "endian_reverse(x)", a function returning the // | |
45 | // value of x with endianness reversed. This provides a customization point for any // | |
46 | // UDT that provides a "endian_reverse" free-function meeting the requirements. // | |
47 | // It must be defined in the same namespace as the UDT itself so that it will be found // | |
48 | // by argument dependent lookup (ADL). // | |
49 | // // | |
50 | //--------------------------------------------------------------------------------------// | |
51 | ||
52 | // customization for exact-length arithmetic types. See doc/conversion.html/#FAQ. | |
53 | // Note: The omission of a overloads for the arithmetic type (typically long, or | |
54 | // long long) not assigned to one of the exact length typedefs is a deliberate | |
55 | // design decision. Such overloads would be non-portable and thus error prone. | |
56 | ||
57 | inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT; | |
58 | inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT; | |
59 | inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT; | |
60 | inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT; | |
61 | inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT; | |
62 | inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT; | |
63 | inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT; | |
64 | inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT; | |
65 | ||
66 | // reverse byte order unless native endianness is big | |
67 | template <class EndianReversible > | |
68 | inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT; | |
69 | // Returns: x if native endian order is big, otherwise endian_reverse(x) | |
70 | template <class EndianReversible > | |
71 | inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT; | |
72 | // Returns: x if native endian order is big, otherwise endian_reverse(x) | |
73 | ||
74 | // reverse byte order unless native endianness is little | |
75 | template <class EndianReversible > | |
76 | inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT; | |
77 | // Returns: x if native endian order is little, otherwise endian_reverse(x) | |
78 | template <class EndianReversible > | |
79 | inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT; | |
80 | // Returns: x if native endian order is little, otherwise endian_reverse(x) | |
81 | ||
82 | // generic conditional reverse byte order | |
83 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
84 | class EndianReversible> | |
85 | inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT; | |
86 | // Returns: If From == To have different values, from. | |
87 | // Otherwise endian_reverse(from). | |
88 | // Remarks: The From == To test, and as a consequence which form the return takes, is | |
89 | // is determined at compile time. | |
90 | ||
91 | // runtime conditional reverse byte order | |
92 | template <class EndianReversible > | |
93 | inline EndianReversible conditional_reverse(EndianReversible from, | |
94 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | |
95 | BOOST_NOEXCEPT; | |
96 | // Returns: from_order == to_order ? from : endian_reverse(from). | |
97 | ||
98 | //------------------------------------------------------------------------------------// | |
99 | ||
100 | ||
101 | // Q: What happened to bswap, htobe, and the other synonym functions based on names | |
102 | // popularized by BSD, OS X, and Linux? | |
103 | // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names | |
104 | // for such functionality. Since macros would cause endless problems with functions | |
105 | // of the same names, and these functions are just synonyms anyhow, they have been | |
106 | // removed. | |
107 | ||
108 | ||
109 | //------------------------------------------------------------------------------------// | |
110 | // // | |
111 | // reverse in place interfaces // | |
112 | // // | |
113 | // user-defined types (UDTs) // | |
114 | // // | |
115 | // All reverse in place function templates are required to be implemented in terms // | |
116 | // of an unqualified call to "endian_reverse_inplace(x)", a function reversing // | |
117 | // the endianness of x, which is a non-const reference. This provides a // | |
118 | // customization point for any UDT that provides a "reverse_inplace" free-function // | |
119 | // meeting the requirements. The free-function must be declared in the same // | |
120 | // namespace as the UDT itself so that it will be found by argument-dependent // | |
121 | // lookup (ADL). // | |
122 | // // | |
123 | //------------------------------------------------------------------------------------// | |
124 | ||
125 | // reverse in place | |
126 | template <class EndianReversible> | |
127 | inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT; | |
128 | // Effects: x = endian_reverse(x) | |
129 | ||
130 | // reverse in place unless native endianness is big | |
131 | template <class EndianReversibleInplace> | |
132 | inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | |
133 | // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) | |
134 | template <class EndianReversibleInplace> | |
135 | inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | |
136 | // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) | |
137 | ||
138 | // reverse in place unless native endianness is little | |
139 | template <class EndianReversibleInplace> | |
140 | inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | |
141 | // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); | |
142 | template <class EndianReversibleInplace> | |
143 | inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | |
144 | // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); | |
145 | ||
146 | // generic conditional reverse in place | |
147 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
148 | class EndianReversibleInplace> | |
149 | inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | |
150 | ||
151 | // runtime reverse in place | |
152 | template <class EndianReversibleInplace> | |
153 | inline void conditional_reverse_inplace(EndianReversibleInplace& x, | |
154 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | |
155 | BOOST_NOEXCEPT; | |
156 | ||
157 | //----------------------------------- end synopsis -------------------------------------// | |
158 | ||
159 | namespace detail | |
160 | { | |
161 | // generic reverse function template implementation approach using std::reverse | |
162 | // suggested by Mathias Gaunard. Primary motivation for inclusion is to have an | |
163 | // independent implementation to test against. | |
164 | ||
165 | template <class T> | |
166 | inline T std_endian_reverse(T x) BOOST_NOEXCEPT | |
167 | { | |
168 | T tmp(x); | |
169 | std::reverse( | |
170 | reinterpret_cast<unsigned char*>(&tmp), | |
171 | reinterpret_cast<unsigned char*>(&tmp) + sizeof(T)); | |
172 | return tmp; | |
173 | } | |
174 | ||
175 | // conditional unaligned reverse copy, patterned after std::reverse_copy | |
176 | template <class T> | |
177 | inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT; | |
178 | template <class T> | |
179 | inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; | |
180 | template <class T> | |
181 | inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT; | |
182 | template <class T> | |
183 | inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; | |
184 | } // namespace detail | |
185 | ||
186 | //--------------------------------------------------------------------------------------// | |
187 | // // | |
188 | // return-by-value implementation // | |
189 | // // | |
190 | // -- portable approach suggested by tymofey, with avoidance of undefined behavior // | |
191 | // as suggested by Giovanni Piero Deretta, with a further refinement suggested // | |
192 | // by Pyry Jahkola. // | |
193 | // -- intrinsic approach suggested by reviewers, and by David Stone, who provided // | |
194 | // his Boost licensed macro implementation (detail/intrinsic.hpp) // | |
195 | // // | |
196 | //--------------------------------------------------------------------------------------// | |
197 | ||
198 | inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT | |
199 | { | |
200 | return x; | |
201 | } | |
202 | ||
203 | inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT | |
204 | { | |
205 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
206 | return (static_cast<uint16_t>(x) << 8) | |
207 | | (static_cast<uint16_t>(x) >> 8); | |
208 | # else | |
209 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x)); | |
210 | # endif | |
211 | } | |
212 | ||
213 | inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT | |
214 | { | |
215 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
216 | uint32_t step16; | |
217 | step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16; | |
218 | return | |
219 | ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00) | |
220 | | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff); | |
221 | # else | |
222 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x)); | |
223 | # endif | |
224 | } | |
225 | ||
226 | inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT | |
227 | { | |
228 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
229 | uint64_t step32, step16; | |
230 | step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32; | |
231 | step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | |
232 | | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; | |
233 | return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8 | |
234 | | (step16 & 0xFF00FF00FF00FF00ULL) >> 8); | |
235 | # else | |
236 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x)); | |
237 | # endif | |
238 | } | |
239 | ||
240 | inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT | |
241 | { | |
242 | return x; | |
243 | } | |
244 | ||
245 | inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT | |
246 | { | |
247 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
248 | return (x << 8) | |
249 | | (x >> 8); | |
250 | # else | |
251 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x); | |
252 | # endif | |
253 | } | |
254 | ||
255 | inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT | |
256 | { | |
257 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
258 | uint32_t step16; | |
259 | step16 = x << 16 | x >> 16; | |
260 | return | |
261 | ((step16 << 8) & 0xff00ff00) | |
262 | | ((step16 >> 8) & 0x00ff00ff); | |
263 | # else | |
264 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x); | |
265 | # endif | |
266 | } | |
267 | ||
268 | inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT | |
269 | { | |
270 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | |
271 | uint64_t step32, step16; | |
272 | step32 = x << 32 | x >> 32; | |
273 | step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | |
274 | | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; | |
275 | return (step16 & 0x00FF00FF00FF00FFULL) << 8 | |
276 | | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; | |
277 | # else | |
278 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x); | |
279 | # endif | |
280 | } | |
281 | ||
282 | template <class EndianReversible > | |
283 | inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT | |
284 | { | |
285 | # ifdef BOOST_BIG_ENDIAN | |
286 | return x; | |
287 | # else | |
288 | return endian_reverse(x); | |
289 | # endif | |
290 | } | |
291 | ||
292 | template <class EndianReversible > | |
293 | inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT | |
294 | { | |
295 | # ifdef BOOST_BIG_ENDIAN | |
296 | return x; | |
297 | # else | |
298 | return endian_reverse(x); | |
299 | # endif | |
300 | } | |
301 | ||
302 | template <class EndianReversible > | |
303 | inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT | |
304 | { | |
305 | # ifdef BOOST_LITTLE_ENDIAN | |
306 | return x; | |
307 | # else | |
308 | return endian_reverse(x); | |
309 | # endif | |
310 | } | |
311 | ||
312 | template <class EndianReversible > | |
313 | inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT | |
314 | { | |
315 | # ifdef BOOST_LITTLE_ENDIAN | |
316 | return x; | |
317 | # else | |
318 | return endian_reverse(x); | |
319 | # endif | |
320 | } | |
321 | ||
322 | namespace detail | |
323 | { | |
324 | // Primary template and specializations to support endian_reverse(). | |
325 | // See rationale in endian_reverse() below. | |
326 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
327 | class EndianReversible> | |
328 | class value_converter ; // primary template | |
329 | template <class T> class value_converter <order::big, order::big, T> | |
330 | {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; | |
331 | template <class T> class value_converter <order::little, order::little, T> | |
332 | {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; | |
333 | template <class T> class value_converter <order::big, order::little, T> | |
334 | {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; | |
335 | template <class T> class value_converter <order::little, order::big, T> | |
336 | {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; | |
337 | } | |
338 | ||
339 | // generic conditional reverse | |
340 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
341 | class EndianReversible> | |
342 | inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT { | |
343 | // work around lack of function template partial specialization by instantiating | |
344 | // a function object of a class that is partially specialized on the two order | |
345 | // template parameters, and then calling its operator(). | |
346 | detail::value_converter <From, To, EndianReversible> tmp; | |
347 | return tmp(from); | |
348 | } | |
349 | ||
350 | // runtime conditional reverse | |
351 | template <class EndianReversible > | |
352 | inline EndianReversible conditional_reverse(EndianReversible from, | |
353 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT | |
354 | { | |
355 | return from_order == to_order ? from : endian_reverse(from); | |
356 | } | |
357 | ||
358 | //--------------------------------------------------------------------------------------// | |
359 | // reverse-in-place implementation // | |
360 | //--------------------------------------------------------------------------------------// | |
361 | ||
362 | // reverse in place | |
363 | template <class EndianReversible> | |
364 | inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT | |
365 | { | |
366 | x = endian_reverse(x); | |
367 | } | |
368 | ||
369 | template <class EndianReversibleInplace> | |
370 | # ifdef BOOST_BIG_ENDIAN | |
371 | inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | |
372 | # else | |
373 | inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | |
374 | { endian_reverse_inplace(x); } | |
375 | # endif | |
376 | template <class EndianReversibleInplace> | |
377 | # ifdef BOOST_BIG_ENDIAN | |
378 | inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | |
379 | # else | |
380 | inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | |
381 | { | |
382 | endian_reverse_inplace(x); | |
383 | } | |
384 | # endif | |
385 | ||
386 | template <class EndianReversibleInplace> | |
387 | # ifdef BOOST_LITTLE_ENDIAN | |
388 | inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | |
389 | # else | |
390 | inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | |
391 | { endian_reverse_inplace(x); } | |
392 | # endif | |
393 | template <class EndianReversibleInplace> | |
394 | # ifdef BOOST_LITTLE_ENDIAN | |
395 | inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | |
396 | # else | |
397 | inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | |
398 | { | |
399 | endian_reverse_inplace(x); | |
400 | } | |
401 | # endif | |
402 | ||
403 | namespace detail | |
404 | { | |
405 | // Primary template and specializations support generic | |
406 | // endian_reverse_inplace(). | |
407 | // See rationale in endian_reverse_inplace() below. | |
408 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
409 | class EndianReversibleInplace> | |
410 | class converter; // primary template | |
411 | template <class T> class converter<order::big, order::big, T> | |
412 | {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; | |
413 | template <class T> class converter<order::little, order::little, T> | |
414 | {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; | |
415 | template <class T> class converter<order::big, order::little, T> | |
416 | {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; | |
417 | template <class T> class converter<order::little, order::big, T> | |
418 | {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; | |
419 | } // namespace detail | |
420 | ||
421 | // generic conditional reverse in place | |
422 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | |
423 | class EndianReversibleInplace> | |
424 | inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | |
425 | { | |
426 | // work around lack of function template partial specialization by instantiating | |
427 | // a function object of a class that is partially specialized on the two order | |
428 | // template parameters, and then calling its operator(). | |
429 | detail::converter<From, To, EndianReversibleInplace> tmp; | |
430 | tmp(x); // call operator () | |
431 | } | |
432 | ||
433 | // runtime reverse in place | |
434 | template <class EndianReversibleInplace> | |
435 | inline void conditional_reverse_inplace(EndianReversibleInplace& x, | |
436 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | |
437 | BOOST_NOEXCEPT | |
438 | { | |
439 | if (from_order != to_order) | |
440 | endian_reverse_inplace(x); | |
441 | } | |
442 | ||
443 | ||
444 | namespace detail | |
445 | { | |
446 | template <class T> | |
447 | inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT | |
448 | { | |
449 | # ifdef BOOST_BIG_ENDIAN | |
450 | std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); | |
451 | # else | |
452 | std::reverse_copy(reinterpret_cast<const char*>(&from), | |
453 | reinterpret_cast<const char*>(&from) + sizeof(T), to); | |
454 | # endif | |
455 | } | |
456 | template <class T> | |
457 | inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT | |
458 | { | |
459 | # ifdef BOOST_BIG_ENDIAN | |
460 | std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); | |
461 | # else | |
462 | std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); | |
463 | # endif | |
464 | } | |
465 | template <class T> | |
466 | inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT | |
467 | { | |
468 | # ifdef BOOST_LITTLE_ENDIAN | |
469 | std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); | |
470 | # else | |
471 | std::reverse_copy(reinterpret_cast<const char*>(&from), | |
472 | reinterpret_cast<const char*>(&from) + sizeof(T), to); | |
473 | # endif | |
474 | } | |
475 | template <class T> | |
476 | inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT | |
477 | { | |
478 | # ifdef BOOST_LITTLE_ENDIAN | |
479 | std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); | |
480 | # else | |
481 | std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); | |
482 | # endif | |
483 | } | |
484 | } // namespace detail | |
485 | } // namespace endian | |
486 | } // namespace boost | |
487 | ||
488 | #endif // BOOST_ENDIAN_CONVERSION_HPP |