forked from boostorg/endian
Compare commits
300 Commits
feature/bu
...
esp-idf-co
Author | SHA1 | Date | |
---|---|---|---|
7719090004 | |||
d1a95acee2 | |||
0dab6737eb | |||
a3f658b15d | |||
423b695ec0 | |||
5ec08e62cd | |||
e35a48c0ea | |||
a9ab336f89 | |||
fa3dd0b853 | |||
39f9394e38 | |||
3951447dac | |||
3a53394b31 | |||
c54c199640 | |||
141af01ead | |||
647e1363a8 | |||
af016adda1 | |||
ccc1def8c9 | |||
e1d8b67380 | |||
6dc25d067d | |||
ab54773e26 | |||
14dd639312 | |||
108c01316f | |||
daca1dce12 | |||
ef89beccfd | |||
3e34e8c011 | |||
40fdf66f24 | |||
783c7e6242 | |||
6477f4abe6 | |||
fa2d87176e | |||
eed8b47703 | |||
9420226cbc | |||
f5b7193778 | |||
b0b9622ceb | |||
84f15c4fb2 | |||
295c225e9e | |||
3853f80886 | |||
7832a88828 | |||
9f122a913c | |||
94b5b7c73f | |||
914d7d5c8d | |||
dffcf99ca6 | |||
4a7242be23 | |||
f07be92a32 | |||
c489997d37 | |||
496e99cbad | |||
e2b622d3da | |||
9ee301b103 | |||
d46d2916a8 | |||
62091e5d0c | |||
a6e1da6a79 | |||
e2fe1d7743 | |||
5df5bc062f | |||
9d248e0f5e | |||
3e2890c243 | |||
8e617a69d1 | |||
74b73c5c03 | |||
7f025ef4b6 | |||
ceb58197d5 | |||
21eed3fd59 | |||
0f33f25eeb | |||
e1b7981a53 | |||
2b101c64a9 | |||
38598d02a3 | |||
073ba8ad7d | |||
a5ae1bb09f | |||
520d37eb9f | |||
81ac17540a | |||
7eaa25ec2a | |||
297a146950 | |||
627fa385f1 | |||
290761ec3d | |||
f143fe172d | |||
94bf4b41f4 | |||
69c020ea8f | |||
3d053160ce | |||
3a50c15a97 | |||
816c7597e3 | |||
7ac116915c | |||
1330d0f3c4 | |||
7854cc109d | |||
1a8b6a498b | |||
b8139ad7a1 | |||
3de20eb340 | |||
7f9a618b8c | |||
57d14c5cc5 | |||
c64f7c3372 | |||
fbc198e75d | |||
b2faa783ad | |||
51f095f019 | |||
59097ada36 | |||
a12049ae04 | |||
af83fc2537 | |||
b015a164f8 | |||
f992e9d3e4 | |||
ac0383f28d | |||
e6136ddf27 | |||
60a5068070 | |||
52bbc9147b | |||
41ee26a8d8 | |||
4054afda70 | |||
22d0d7bcd1 | |||
0704c271b1 | |||
cd84a98a88 | |||
33dea996a7 | |||
704cd4d9f7 | |||
a4bc0f1a44 | |||
3c296ff707 | |||
cc28f5d658 | |||
80d926e700 | |||
4ef4d05cdf | |||
b816d97235 | |||
96ef03b6cb | |||
7555b7801d | |||
e68d8f939c | |||
79af9fba53 | |||
79c3add907 | |||
fe18fdbb3b | |||
8df14956d4 | |||
b0cc5e64d3 | |||
d40a3ac3f4 | |||
39eab827cf | |||
b7ffb62e09 | |||
f0f8e398d6 | |||
b29b3dfc10 | |||
f2dc045c43 | |||
ff59429171 | |||
8200306bf1 | |||
dad7086b37 | |||
c59eb627ad | |||
630e09942b | |||
cd8fbbdbcb | |||
9efbcd7c7b | |||
43d21860a4 | |||
15e6923325 | |||
6b5792647c | |||
f77a318c37 | |||
8e3eccaa14 | |||
6047813081 | |||
c42fcb09bc | |||
64607e2e2e | |||
d9e5fb0d41 | |||
e58970b167 | |||
2df48f1427 | |||
26b0170a6e | |||
18d86d3f36 | |||
19e382d25a | |||
a2025a9320 | |||
e9feff0abb | |||
7c35802f6a | |||
ac96e4ac24 | |||
c84e015573 | |||
f4f3c433dd | |||
cdfe2eb3cb | |||
59b4062507 | |||
a6aaec46f5 | |||
9ffe32f740 | |||
0e349f3d5b | |||
607cc7da73 | |||
cd17067afb | |||
01278f951d | |||
0427a95459 | |||
8f890ed3c3 | |||
146c1af963 | |||
6b65a4b6ed | |||
7afa3e307b | |||
eee3e1bc7a | |||
185573f341 | |||
01146c9558 | |||
6a84756afb | |||
2d60299b71 | |||
3c6c06616d | |||
2bd479044b | |||
5623e48fb5 | |||
de33887009 | |||
95178e3cfb | |||
019fb85ea9 | |||
a564b97dab | |||
e5a1b739c2 | |||
e08864d648 | |||
e6266a7a60 | |||
c6f6c45bb8 | |||
28615311d9 | |||
2b91e9e911 | |||
533c82fa92 | |||
ebb282fbe0 | |||
a3f1d70453 | |||
8aef2d08af | |||
dafb9b1795 | |||
96c2e6dacb | |||
1b589e28d0 | |||
9f67f19d35 | |||
de4aadcb11 | |||
84273c7139 | |||
9cbd708ce5 | |||
59126b39ae | |||
bde5937912 | |||
e5753d13e2 | |||
2837f3b9c5 | |||
7edf9a030a | |||
553792d40c | |||
07ec535600 | |||
327b501169 | |||
f6998d2406 | |||
e93f6a2270 | |||
62802fee96 | |||
10877d3667 | |||
d4738d8598 | |||
0d5adab378 | |||
4648d237f0 | |||
134b225378 | |||
674adbd592 | |||
69f5b950a2 | |||
34542134be | |||
9c0e938c3c | |||
4bfe758320 | |||
b5a79243a2 | |||
b647051422 | |||
c6aac76029 | |||
af744e9485 | |||
4b4123a0fa | |||
a2b044f181 | |||
ac7a8e1696 | |||
d89e6ddc62 | |||
739bc40bfc | |||
754a4144ec | |||
2db73ab893 | |||
dc263dd9ac | |||
51ecbb06e2 | |||
b51593c766 | |||
d1865063ad | |||
1b0a41e6cb | |||
91985423e4 | |||
484c635316 | |||
f14f080359 | |||
5c26514ded | |||
117ee622c2 | |||
55714f0d0a | |||
bf0dec92d0 | |||
636a7bfd6e | |||
cd57e01f9c | |||
f0f2505f9b | |||
d612bee5b9 | |||
fdc8965842 | |||
3dffbdbcb4 | |||
01f7e359bb | |||
5caf1d16c8 | |||
a15f9420cb | |||
e532e9c34d | |||
5ab08db7a4 | |||
44542694e3 | |||
cea2be8023 | |||
ff4b22bdec | |||
affdcac443 | |||
7460870381 | |||
13b0d7b9ba | |||
4f2a715c9f | |||
09ae6c961f | |||
adc09abc7a | |||
072b495240 | |||
482bcb0855 | |||
a968c67510 | |||
63a5b4ff54 | |||
9c0cbae556 | |||
b6b03ea900 | |||
963f00ec8f | |||
c62aa232e1 | |||
8b7a140f0e | |||
b0ef03b9d6 | |||
d0dc573ec1 | |||
6dcda67ed6 | |||
c0fbae2d2a | |||
f184fd934e | |||
09ead95d10 | |||
2a4584a413 | |||
27a6d36327 | |||
512287dfa7 | |||
3d814f4f52 | |||
adee2fe513 | |||
e9ae69f3d0 | |||
35f4c47a22 | |||
10bcb52d97 | |||
810f5453a6 | |||
321d5a087a | |||
0cdcb5f048 | |||
c440b3b7da | |||
a32c13451b | |||
08b5a27461 | |||
04d079fa61 | |||
ca8b904502 | |||
48f7363cd7 | |||
4669f1b04b | |||
25143c6b9a | |||
48ea9cc333 | |||
79709fe054 | |||
25a00586a2 | |||
c1e46997c8 | |||
5407a099d3 | |||
fb87b21a0d | |||
d15b2fdb1c | |||
6de2f69b77 |
194
.drone.jsonnet
Normal file
194
.drone.jsonnet
Normal file
@ -0,0 +1,194 @@
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
local library = "endian";
|
||||
|
||||
local triggers =
|
||||
{
|
||||
branch: [ "master", "develop", "feature/*" ]
|
||||
};
|
||||
|
||||
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
|
||||
local asan = { ASAN: '1' };
|
||||
|
||||
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "linux",
|
||||
arch: arch
|
||||
},
|
||||
steps:
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "exec",
|
||||
trigger: triggers,
|
||||
platform: {
|
||||
"os": "darwin",
|
||||
"arch": arch
|
||||
},
|
||||
node: {
|
||||
"os": osx_version
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
name: "everything",
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "windows",
|
||||
arch: arch
|
||||
},
|
||||
"steps":
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.4",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x' },
|
||||
"g++-4.4",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.6 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x', ADDRMD: '32,64' },
|
||||
"g++-4.6-multilib",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.7 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x', ADDRMD: '32,64' },
|
||||
"g++-4.7-multilib",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.8* 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 14.04 GCC 4.9 32/64",
|
||||
"cppalliance/droneubuntu1404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11', ADDRMD: '32,64' },
|
||||
"g++-4.9-multilib",
|
||||
[ "ppa:ubuntu-toolchain-r/test" ],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 ARM64 32/64",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 S390x 32/64",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' },
|
||||
arch="s390x",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 32 ASAN",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14,17,20', ADDRMD: '32' } + asan,
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 64 ASAN",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14,17,20', ADDRMD: '64' } + asan,
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 14 UBSAN",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + ubsan,
|
||||
"clang-14",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 14 ASAN",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' } + asan,
|
||||
"clang-14",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2017 msvc-14.1",
|
||||
"cppalliance/dronevs2017",
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
|
||||
),
|
||||
]
|
23
.drone/drone.bat
Normal file
23
.drone/drone.bat
Normal file
@ -0,0 +1,23 @@
|
||||
@REM Copyright 2022 Peter Dimov
|
||||
@REM Distributed under the Boost Software License, Version 1.0.
|
||||
@REM https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ECHO ON
|
||||
|
||||
set LIBRARY=%1
|
||||
set DRONE_BUILD_DIR=%CD%
|
||||
|
||||
set BOOST_BRANCH=develop
|
||||
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
|
||||
python tools/boostdep/depinst/depinst.py %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
24
.drone/drone.sh
Executable file
24
.drone/drone.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
387
.github/workflows/ci.yml
vendored
Normal file
387
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,387 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-18.04
|
||||
install: g++-4.8-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-5
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-5-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-6
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-6-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: g++-7-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-9-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-10-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-11
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11-multilib
|
||||
address-model: 32,64
|
||||
- toolset: gcc-12
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-22.04
|
||||
install: g++-12-multilib
|
||||
address-model: 32,64
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-10
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-11
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-20.04
|
||||
install: clang-12
|
||||
- toolset: clang
|
||||
compiler: clang++-13
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-22.04
|
||||
install: clang-13
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-22.04
|
||||
install: clang-14
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
- name: Create user-config.jam
|
||||
if: matrix.compiler
|
||||
run: |
|
||||
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root
|
||||
export ADDRMD=${{matrix.address-model}}
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.0
|
||||
cxxstd: 14,latest
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
|
||||
|
||||
posix-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Use library with add_subdirectory
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
|
||||
mkdir __build__ && cd __build__
|
||||
cmake ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install
|
||||
|
||||
- name: Use the installed library
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
|
||||
|
||||
- name: Build tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target tests
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
ctest --output-on-failure --no-tests=error
|
430
.travis.yml
Normal file
430
.travis.yml
Normal file
@ -0,0 +1,430 @@
|
||||
# Copyright 2016-2020 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
dist: xenial
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-multilib
|
||||
|
||||
- os: linux
|
||||
arch: arm64
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
|
||||
|
||||
- os: linux
|
||||
arch: ppc64le
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
|
||||
|
||||
- os: linux
|
||||
arch: s390x
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.4
|
||||
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.4
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.6
|
||||
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.7
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.8
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- os: linux
|
||||
compiler: g++-4.9
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-5
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-6
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: g++-10
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.3
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.4
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.6
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.7
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.9
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-4.0
|
||||
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-xenial-7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-xenial-8
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-10
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-11
|
||||
env: TOOLSET=clang COMPILER=clang++-11 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-11
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-12
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-12 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-12
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang++-libc++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-libc++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode11.3
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64 UBSAN_OPTIONS=print_stacktrace=1
|
||||
|
||||
- os: linux
|
||||
env: CMAKE_TEST=1
|
||||
script:
|
||||
- mkdir __build__ && cd __build__
|
||||
- cmake -DBOOST_ENABLE_CMAKE=1 -DBUILD_TESTING=ON -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=endian ..
|
||||
- ctest --output-on-failure -R boost_endian
|
||||
|
||||
- os: linux
|
||||
env: CMAKE_SUBDIR_TEST=1
|
||||
install:
|
||||
- BOOST_BRANCH=develop
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/assert.git ../assert
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/config.git ../config
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/core.git ../core
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/static_assert.git ../static_assert
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/type_traits.git ../type_traits
|
||||
script:
|
||||
- cd test/cmake_subdir_test && mkdir __build__ && cd __build__
|
||||
- cmake ..
|
||||
- cmake --build .
|
||||
- cmake --build . --target check
|
||||
|
||||
- os: linux
|
||||
env: CMAKE_INSTALL_TEST=1
|
||||
script:
|
||||
- pip install --user cmake
|
||||
- mkdir __build__ && cd __build__
|
||||
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=endian -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
- cmake --build . --target install
|
||||
- cd ../libs/endian/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
- cmake --build .
|
||||
- cmake --build . --target check
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
- cd ..
|
||||
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/boostdep
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/endian
|
||||
- python tools/boostdep/depinst/depinst.py endian
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 -j3 libs/endian/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
47
CMakeLists.txt
Normal file
47
CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright 2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
if(NOT DEFINED IDF_TARGET)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(boost_endian VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_endian INTERFACE)
|
||||
add_library(Boost::endian ALIAS boost_endian)
|
||||
|
||||
target_include_directories(boost_endian INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_endian
|
||||
INTERFACE
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::static_assert
|
||||
Boost::type_traits
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${headers}
|
||||
INCLUDE_DIRS
|
||||
include
|
||||
REQUIRES
|
||||
boost_config
|
||||
boost_core
|
||||
boost_static_assert
|
||||
boost_type_traits
|
||||
)
|
||||
|
||||
endif()
|
||||
|
24
README
24
README
@ -1,24 +0,0 @@
|
||||
Boost Endian library
|
||||
|
||||
To experiment with the Endian library, various other boost libraries must be
|
||||
available. So you need to clone a current version of boost if you
|
||||
have not already done so.
|
||||
|
||||
Boost.Endian is a header-only library, so there is no need to run a build
|
||||
for it, although you may need to do a "b2 headers".
|
||||
|
||||
If your clone of boost is already in place, please remember to:
|
||||
|
||||
cd modular-boost
|
||||
git pull
|
||||
git submodule update --init
|
||||
git submodule update
|
||||
./b2 headers
|
||||
|
||||
On Windows, change the "./" is omitted.
|
||||
|
||||
---------------------------
|
||||
Copyright Beman Dawes, 2013
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Boost.Endian
|
||||
|
||||
The Endian library provides facilities for dealing with
|
||||
[endianness](https://en.wikipedia.org/wiki/Endianness).
|
||||
It's part of Boost since release 1.58.0. See
|
||||
[the documentation](http://boost.org/libs/endian) for more information.
|
||||
|
||||
## Supported compilers
|
||||
|
||||
* g++ 4.4 or later
|
||||
* clang++ 3.3 or later
|
||||
* Visual Studio 2008 or later
|
||||
|
||||
Tested on [Travis](https://travis-ci.org/boostorg/endian/) and
|
||||
[Appveyor](https://ci.appveyor.com/project/pdimov/endian/).
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the
|
||||
[Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
66
appveyor.yml
Normal file
66
appveyor.yml
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 2016-2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
|
||||
ADDRMD: 32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-12.0,msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1,clang-win
|
||||
CXXSTD: 14,17
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: msvc-14.2
|
||||
CXXSTD: 14,17
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- cd ..
|
||||
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/boostdep
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\endian\
|
||||
- python tools/boostdep/depinst/depinst.py endian
|
||||
- cmd /c bootstrap
|
||||
- b2 -d0 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- b2 -j3 libs/endian/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
|
@ -1,4 +1,4 @@
|
||||
# Build endian/test/speed_test.cpp
|
||||
# Build and install benchmark programs
|
||||
|
||||
# Copyright Beman Dawes 2013
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
@ -7,16 +7,19 @@
|
||||
project
|
||||
: source-location ../test : requirements
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
<library>/boost/timer//boost_timer
|
||||
;
|
||||
|
||||
SOURCES = speed_test speed_test_functions ;
|
||||
|
||||
exe "speed_test"
|
||||
: $(SOURCES).cpp ../../timer/build//boost_timer
|
||||
: $(SOURCES).cpp
|
||||
: <toolset>gcc:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
exe "loop_time_test"
|
||||
: loop_time_test.cpp ../../timer/build//boost_timer
|
||||
exe "loop_time_test"
|
||||
: loop_time_test.cpp
|
||||
: <toolset>gcc:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
install bin : speed_test loop_time_test ;
|
12
benchmark/test.bat
Normal file
12
benchmark/test.bat
Normal file
@ -0,0 +1,12 @@
|
||||
b2 -a toolset=msvc-14.0 variant=release link=static address-model=64
|
||||
bin\loop_time_test 1000 >msvc-loop-time.html
|
||||
msvc-loop-time.html
|
||||
|
||||
echo The GCC static build does not work on Windows, probably because of a bjam/b2 bug
|
||||
b2 -a toolset=gcc-c++11 variant=release link=static address-model=64
|
||||
bin\loop_time_test 1000 >gcc-loop-time.html
|
||||
gcc-loop-time.html
|
||||
|
||||
rem Copyright Beman Dawes 2015
|
||||
rem Distributed under the Boost Software License, Version 1.0.
|
||||
rem See www.boost.org/LICENSE_1_0.txt
|
2
doc/.gitignore
vendored
Normal file
2
doc/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/html/
|
||||
/pdf/
|
27
doc/Jamfile
Normal file
27
doc/Jamfile
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright 2019 Glen Joseph Fernandes
|
||||
# (glenjofe@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import asciidoctor ;
|
||||
|
||||
html endian.html : endian.adoc ;
|
||||
|
||||
install html_ : endian.html : <location>html ;
|
||||
|
||||
pdf endian.pdf : endian.adoc ;
|
||||
|
||||
explicit endian.pdf ;
|
||||
|
||||
install pdf_ : endian.pdf : <location>pdf ;
|
||||
|
||||
explicit pdf_ ;
|
||||
|
||||
alias boostdoc ;
|
||||
|
||||
explicit boostdoc ;
|
||||
|
||||
alias boostrelease : html_ ;
|
||||
|
||||
explicit boostrelease ;
|
@ -1,691 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Endian Arithmetic Types</title>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="../../../index.html">
|
||||
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86"></a></td>
|
||||
<td align="middle">
|
||||
<b>
|
||||
<font size="6">Endian Arithmetic Types</font> </b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
|
||||
<tr>
|
||||
<td><b><a href="../../../index.htm">Boost Home</a>
|
||||
<a href="index.html">Endian Home</a>
|
||||
<a href="conversion.html">Conversion Functions</a>
|
||||
<a href="arithmetic.html">Arithmetic Types</a>
|
||||
<a href="buffers.html">Buffer Types</a></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<i><b>Contents</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Example">Example</a><br>
|
||||
<a href="#Limitations">Limitations</a><br>
|
||||
<a href="#Feature-set">Feature set</a><br>
|
||||
<a href="#Types">Enums and typedefs</a><br>
|
||||
<a href="#Class_template_endian">Class template <code>endian</code></a><br>
|
||||
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Members">Members</a><br>
|
||||
<a href="#Stream-inserter">Stream inserter</a><br>
|
||||
<a href="#Stream-extractor">Stream extractor</a><br>
|
||||
<a href="#FAQ">FAQ</a><br>
|
||||
<a href="#Design">Design</a><br>
|
||||
<a href="#Experience">Experience</a><br>
|
||||
<a href="#Motivating-use-cases">Motivating use cases</a><br>
|
||||
<a href="#C++0x">C++11</a><br>
|
||||
<a href="#Compilation">Compilation</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<b><i>Headers</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="../include/boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
||||
<a href="../include/boost/endian/buffers.hpp"><boost/endian/buffers.hpp></a><br>
|
||||
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>Header <a href="arithmetic.html">boost/endian/arithmetic.hpp</a>
|
||||
provides integer and floating point binary types with control over
|
||||
byte order, value type, size, and alignment. Typedefs provide easy-to-use names
|
||||
for common configurations.</p>
|
||||
<p>These types provide portable byte-holders for integer data, independent of
|
||||
particular computer architectures. Use cases almost always involve I/O, either via files or
|
||||
network connections. Although data portability is the primary motivation, these
|
||||
integer byte-holders may
|
||||
also be used to reduce memory use, file size, or network activity since they
|
||||
provide binary integer sizes not otherwise available.</p>
|
||||
<p>Such integer byte-holder types are traditionally called <b><i>
|
||||
endian</i></b> types. See the
|
||||
<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for
|
||||
a full
|
||||
exploration of <b><i>endianness</i></b>, including definitions of <i><b>big
|
||||
endian</b></i> and <i><b>little endian</b></i>.</p>
|
||||
<p>Boost endian integers provide the same full set of C++ assignment,
|
||||
arithmetic, and relational operators as C++ standard integral types, with
|
||||
the standard semantics.</p>
|
||||
<p>Unary arithmetic operators are <code>+</code>, <code>-</code>, <code>~</code>,
|
||||
<code>!</code>, prefix and postfix <code>--</code> and <code>++</code>. Binary
|
||||
arithmetic operators are <code>+</code>, <code>+=</code>, <code>-</code>, <code>
|
||||
-=</code>, <code>*</code>, <code>*=</code>, <code>/</code>, <code>/=</code>,
|
||||
<code>%/ %=</code>, <code>&</code>, <code>&=</code>, <code>|</code>, <code>|=</code>,
|
||||
<code>^</code>, <code>^=</code>, <code><<</code>, <code><<=</code>, <code>>></code>,
|
||||
<code>>>=</code>. Binary relational operators are <code>==</code>, <code>!=</code>,
|
||||
<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>.</p>
|
||||
<p>Automatic implicit conversion to the underlying value type is provided. A
|
||||
conversion constructor from the underlying value type is provided. </p>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a
|
||||
binary file containing four byte big-endian and little-endian integers:</p>
|
||||
<blockquote>
|
||||
<pre>#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format. It seems odd
|
||||
// to mix big and little endians in the same file - but this is a real-world
|
||||
// format and users wishing to write low level code manipulating these files
|
||||
// must deal with the mixed endianness.
|
||||
|
||||
struct header
|
||||
{
|
||||
big_int32_t file_code;
|
||||
big_int32_t file_length;
|
||||
little_int32_t version;
|
||||
little_int32_t shape_type;
|
||||
};
|
||||
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
|
||||
|
||||
header h;
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof(header);
|
||||
h.version = 1;
|
||||
h.shape_type = 0x01020304;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes
|
||||
// used for binary file operations when ultimate efficiency is important. Such
|
||||
// I/O is often performed in some C++ wrapper class, but to drive home the
|
||||
// point that endian integers are often used in fairly low-level code that does
|
||||
// bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
|
||||
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>After compiling and executing <a href="../example/endian_example.cpp">endian_example.cpp</a>,
|
||||
a hex dump of <code>test.dat</code> shows:</p>
|
||||
<blockquote>
|
||||
<pre>01020304 00000010 01000000 04030201</pre>
|
||||
</blockquote>
|
||||
<p>Notice that the first two 32-bit integers are big endian while the second two
|
||||
are little endian, even though the machine this was compiled and run on was
|
||||
little endian.</p>
|
||||
<h2><a name="Limitations">Limitations</a></h2>
|
||||
<p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code>
|
||||
is some other value, compilation will result in an <code>#error</code>. This
|
||||
restriction is in place because the design, implementation, testing, and
|
||||
documentation has only considered issues related to 8-bit bytes, and there have
|
||||
been no real-world use cases presented for other sizes.</p>
|
||||
<p>In C++03, <code>endian</code> does not meet the requirements for POD types
|
||||
because it has constructors, private data members, and a base class. This means
|
||||
that common use cases are relying on unspecified behavior in that the C++
|
||||
Standard does not guarantee memory layout for non-POD types. This has not been a
|
||||
problem in practice since all known C++ compilers do layout memory as if <code>
|
||||
endian</code> were a POD type. In C++11, it is possible to specify the
|
||||
default constructor as trivial, and private data members and base classes will
|
||||
no longer disqualify a type from being a POD. Thus under C++11, <code>endian</code>
|
||||
will no longer be relying on unspecified behavior.</p>
|
||||
<h2><a name="Feature-set">Feature set</a></h2>
|
||||
<ul>
|
||||
<li>Big endian| little endian | native endian byte ordering.</li>
|
||||
<li>Signed | unsigned</li>
|
||||
<li>Unaligned | aligned</li>
|
||||
<li>Integer | floating point</li>
|
||||
<li>1-8 byte (unaligned) | 2, 4, 8 byte (aligned)</li>
|
||||
<li>Choice of value type</li>
|
||||
</ul>
|
||||
<h2>Enums and t<a name="Types">ypedefs</a></h2>
|
||||
<p>Two scoped enums are provided:</p>
|
||||
<blockquote>
|
||||
<pre>enum class order {big, little, native};
|
||||
|
||||
enum class align {no, yes}; </pre>
|
||||
</blockquote>
|
||||
<p>One class template is provided:</p>
|
||||
<blockquote>
|
||||
<pre>template <order Order, typename T, std::size_t n_bits, align A = align::no>
|
||||
class endian_arithmetic;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Typedefs, such as <code>big_int32_t</code>, provide convenient naming
|
||||
conventions for common use cases:</p>
|
||||
<blockquote>
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%">
|
||||
<tr>
|
||||
<td width="18%" align="center"><b><i>Name</i></b></td>
|
||||
<td width="10%" align="center"><b><i>Endianness</i></b></td>
|
||||
<td width="49%" align="center"><b><i>Alignment</i></b></td>
|
||||
<td width="10%" align="center"><b><i>Sign</i></b></td>
|
||||
<td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_int</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_int</code><b><i>n</i></b><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_int</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_uint</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
</tr>
|
||||
</table>
|
||||
</blockquote>
|
||||
<p>The unaligned types do not cause compilers to insert padding bytes in classes
|
||||
and structs. This is an important characteristic that can be exploited to minimize wasted space in
|
||||
memory, files, and network transmissions. </p>
|
||||
<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF">
|
||||
Code that uses a</span>ligned types is possibly non-portable because alignment
|
||||
requirements vary between hardware architectures and because alignment may be
|
||||
affected by compiler switches or pragmas. For example, alignment of an 64-bit
|
||||
integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types
|
||||
are only available on architectures with 16, 32, and 64-bit integer types. </p>
|
||||
<p><b><i>Note:</i></b> One-byte types
|
||||
have identical
|
||||
functionality. They are provided to improve code readability and searchability.</p>
|
||||
<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_arithmetic</code></h2>
|
||||
<p>An endian is an integer byte-holder with user-specified <a href="#endianness">
|
||||
endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The
|
||||
usual operations on integers are supplied.</p>
|
||||
<h3><a name="Synopsis">Synopsis</a></h3>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
// C++11 features emulated if not available
|
||||
|
||||
enum class <a name="order">order</a>
|
||||
{
|
||||
big, // big-endian
|
||||
little, // little-endian
|
||||
native = <b><i>implementation-defined</i></b> // same as order::big or order::little<b><i>
|
||||
</i></b>};
|
||||
|
||||
enum class <a name="alignment">align</a> {no, yes};
|
||||
|
||||
template <order Order, class T, std::size_t n_bits, align A = align::no>
|
||||
class endian_arithmetic
|
||||
: public endian_buffer<Order, T, n_bits, A>
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
// if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 POD's are not
|
||||
// available then these two constructors will not be present
|
||||
<a href="#endian">endian_arithmetic</a>() noexcept = default;
|
||||
<a href="#explicit-endian">endian_arithmetic</a>(T v) noexcept;
|
||||
|
||||
endian_arithmetic& <a href="#operator-eq">operator=</a>(T v) noexcept;
|
||||
<a href="#operator-T">operator value_type</a>() const noexcept;
|
||||
value_type value() const noexcept; // exposition only; see endian_buffer
|
||||
const char* <a href="#data">data</a>() const noexcept; // exposition only; see endian_buffer
|
||||
|
||||
// arithmetic operations
|
||||
// note that additional operations are provided by the value_type
|
||||
value_type operator+(const endian& x) noexcept;
|
||||
endian& operator+=(endian& x, value_type y) noexcept;
|
||||
endian& operator-=(endian& x, value_type y) noexcept;
|
||||
endian& operator*=(endian& x, value_type y) noexcept;
|
||||
endian& operator/=(endian& x, value_type y) noexcept;
|
||||
endian& operator%=(endian& x, value_type y) noexcept;
|
||||
endian& operator&=(endian& x, value_type y) noexcept;
|
||||
endian& operator|=(endian& x, value_type y) noexcept;
|
||||
endian& operator^=(endian& x, value_type y) noexcept;
|
||||
endian& operator<<=(endian& x, value_type y) noexcept;
|
||||
endian& operator>>=(endian& x, value_type y noexcept;
|
||||
value_type operator<<(const endian& x, value_type y) noexcept;
|
||||
value_type operator>>(const endian& x, value_type y) noexcept;
|
||||
endian& operator++(endian& x) noexcept;
|
||||
endian& operator--(endian& x) noexcept;
|
||||
endian operator++(endian& x, int) noexcept;
|
||||
endian operator--(endian& x, int) noexcept;
|
||||
|
||||
// Stream inserter
|
||||
template <class charT, class traits>
|
||||
friend std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const T& x);
|
||||
|
||||
// Stream extractor
|
||||
template <class charT, class traits>
|
||||
friend std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, T& x);
|
||||
};
|
||||
|
||||
// typedefs
|
||||
|
||||
// aligned big endian floating point types
|
||||
typedef endian<order::big, float, 32, align::yes> big_float32_t;
|
||||
typedef endian<order::big, double, 64, align::yes> big_float64_t;
|
||||
|
||||
// aligned little endian floating point types
|
||||
typedef endian<order::little, float, 32, align::yes> little_float32_t;
|
||||
typedef endian<order::little, double, 64, align::yes> little_float64_t;
|
||||
|
||||
// unaligned big endian floating point types
|
||||
typedef endian<order::big, float, 32, align::no> big_float32un_t;
|
||||
typedef endian<order::big, double, 64, align::no> big_float64un_t;
|
||||
|
||||
// unaligned little endian floating point types
|
||||
typedef endian<order::little, float, 32, align::no> little_float32un_t;
|
||||
typedef endian<order::little, double, 64, align::no> little_float64un_t;
|
||||
|
||||
// aligned big endian signed integer types
|
||||
typedef endian<order::big, int16_t, 16, align::yes> big_int16_t;
|
||||
typedef endian<order::big, int32_t, 32, align::yes> big_int32_t;
|
||||
typedef endian<order::big, int64_t, 64, align::yes> big_int64_t;
|
||||
|
||||
// aligned big endian unsigned integer types
|
||||
typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_t;
|
||||
typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_t;
|
||||
typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_t;
|
||||
|
||||
// aligned little endian signed integer types
|
||||
typedef endian<order::little, int16_t, 16, align::yes> little_int16_t;
|
||||
typedef endian<order::little, int32_t, 32, align::yes> little_int32_t;
|
||||
typedef endian<order::little, int64_t, 64, align::yes> little_int64_t;
|
||||
|
||||
// aligned little endian unsigned integer types
|
||||
typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_t;
|
||||
typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_t;
|
||||
typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_t;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for that use case
|
||||
|
||||
// unaligned big endian signed integer types
|
||||
typedef endian<order::big, int_least8_t, 8> big_int8_ut;
|
||||
typedef endian<order::big, int_least16_t, 16> big_int16_ut;
|
||||
typedef endian<order::big, int_least32_t, 24> big_int24_ut;
|
||||
typedef endian<order::big, int_least32_t, 32> big_int32_ut;
|
||||
typedef endian<order::big, int_least64_t, 40> big_int40_ut;
|
||||
typedef endian<order::big, int_least64_t, 48> big_int48_ut;
|
||||
typedef endian<order::big, int_least64_t, 56> big_int56_ut;
|
||||
typedef endian<order::big, int_least64_t, 64> big_int64_ut;
|
||||
|
||||
// unaligned big endian unsigned integer types
|
||||
typedef endian<order::big, uint_least8_t, 8> big_uint8_ut;
|
||||
typedef endian<order::big, uint_least16_t, 16> big_uint16_ut;
|
||||
typedef endian<order::big, uint_least32_t, 24> big_uint24_ut;
|
||||
typedef endian<order::big, uint_least32_t, 32> big_uint32_ut;
|
||||
typedef endian<order::big, uint_least64_t, 40> big_uint40_ut;
|
||||
typedef endian<order::big, uint_least64_t, 48> big_uint48_ut;
|
||||
typedef endian<order::big, uint_least64_t, 56> big_uint56_ut;
|
||||
typedef endian<order::big, uint_least64_t, 64> big_uint64_ut;
|
||||
|
||||
// unaligned little endian signed integer types
|
||||
typedef endian<order::little, int_least8_t, 8> little_int8_ut;
|
||||
typedef endian<order::little, int_least16_t, 16> little_int16_ut;
|
||||
typedef endian<order::little, int_least32_t, 24> little_int24_ut;
|
||||
typedef endian<order::little, int_least32_t, 32> little_int32_ut;
|
||||
typedef endian<order::little, int_least64_t, 40> little_int40_ut;
|
||||
typedef endian<order::little, int_least64_t, 48> little_int48_ut;
|
||||
typedef endian<order::little, int_least64_t, 56> little_int56_ut;
|
||||
typedef endian<order::little, int_least64_t, 64> little_int64_ut;
|
||||
|
||||
// unaligned little endian unsigned integer types
|
||||
typedef endian<order::little, uint_least8_t, 8> little_uint8_ut;
|
||||
typedef endian<order::little, uint_least16_t, 16> little_uint16_ut;
|
||||
typedef endian<order::little, uint_least32_t, 24> little_uint24_ut;
|
||||
typedef endian<order::little, uint_least32_t, 32> little_uint32_ut;
|
||||
typedef endian<order::little, uint_least64_t, 40> little_uint40_ut;
|
||||
typedef endian<order::little, uint_least64_t, 48> little_uint48_ut;
|
||||
typedef endian<order::little, uint_least64_t, 56> little_uint56_ut;
|
||||
typedef endian<order::little, uint_least64_t, 64> little_uint64_ut;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef <b><i>implementation-defined</i></b>_int8_t native_int8_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int16_t native_int16_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int24_t native_int24_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int32_t native_int32_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int40_t native_int40_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int48_t native_int48_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int56_t native_int56_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int64_t native_int64_ut;
|
||||
|
||||
// unaligned native endian unsigned integer types
|
||||
typedef <b><i>implementation-defined</i></b>_uint8_t native_uint8_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint16_t native_uint16_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint24_t native_uint24_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint32_t native_uint32_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint40_t native_uint40_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint48_t native_uint48_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint56_t native_uint56_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint64_t native_uint64_ut;
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost</pre>
|
||||
<p>The <i><b><code>implementation-defined</code></b></i> text above is either
|
||||
<code>big</code> or <code>little</code> according to the endianness of the
|
||||
platform.</p>
|
||||
<h3><a name="Members">Members</a></h3>
|
||||
<div dir="ltr">
|
||||
<pre><code><a name="endian">endian</a>() = default; // C++03: endian(){}</code></pre>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of type <code>endian<E, T, n_bits, A></code>.</p>
|
||||
</blockquote>
|
||||
<pre><code><a name="explicit-endian">endian</a>(T v);</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of type <code>endian<E, T, n_bits, A></code>.</p>
|
||||
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
|
||||
constructed object.</p>
|
||||
</blockquote>
|
||||
<pre><code>endian& <a name="operator-eq">operator=</a>(T v);</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
|
||||
constructed object.</p>
|
||||
<p><i>Returns:</i> <code>*this</code>.</p>
|
||||
</blockquote>
|
||||
<pre><code><a name="operator-T">operator T</a>() const;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> The current value stored in <code>*this</code>, converted to
|
||||
<code>value_type</code>.</p>
|
||||
</blockquote>
|
||||
<pre><code>const char* <a name="data">data</a>() const;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> A pointer to the first byte of the endian binary value stored
|
||||
in <code>*this</code>.</p>
|
||||
</blockquote>
|
||||
<h3>Other operators</h3>
|
||||
<p>Other operators on endian objects are forwarded to the equivalent
|
||||
operator on <code>value_type</code>.</p>
|
||||
<h3><a name="Stream-inserter">Stream inserter</a></h3>
|
||||
<pre>template <class charT, class traits>
|
||||
friend std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const T& x);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>os << +x</code>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="Stream-extractor">Stream extractor</a></h3>
|
||||
<pre>template <class charT, class traits>
|
||||
friend std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, T& x);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p><i>Effects: </i>As if:</p>
|
||||
<blockquote>
|
||||
<pre>T i;
|
||||
if (is >> i)
|
||||
x = i;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p><i>Returns: </i><code>is</code><i>.</i></p>
|
||||
</blockquote>
|
||||
<h2><a name="FAQ">FAQ</a></h2>
|
||||
|
||||
<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide
|
||||
FAQ.</p>
|
||||
|
||||
<p><b>Why not just use Boost.Serialization?</b> Serialization involves a
|
||||
conversion for every object involved in I/O. Endian integers require no
|
||||
conversion or copying. They are already in the desired format for binary I/O.
|
||||
Thus they can be read or written in bulk.</p>
|
||||
<p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several
|
||||
<a href="#Compilation">macros</a> are available to force PODness in all cases.</p>
|
||||
<p><b>What are the implications of endian integer types not being POD's with C++03
|
||||
compilers?</b> They
|
||||
can't be used in unions. Also, compilers aren't required to align or lay
|
||||
out storage in portable ways, although this potential problem hasn't prevented
|
||||
use of Boost.Endian with
|
||||
real compilers.</p>
|
||||
<p><b>What good is <i>native </i>endianness?</b> It provides alignment and
|
||||
size guarantees not available from the built-in types. It eases generic
|
||||
programming.</p>
|
||||
<p><b>Why bother with the aligned endian types?</b> Aligned integer operations
|
||||
may be faster (as much as 10 to 20 times faster) if the endianness and alignment of
|
||||
the type matches the endianness and alignment requirements of the machine. The code,
|
||||
however, is
|
||||
likely to be somewhat less portable than with the unaligned types.</p>
|
||||
<p><b>Why provide the arithmetic operations?</b> Providing a full set of operations reduces program
|
||||
clutter and makes code both easier to write and to read. Consider
|
||||
incrementing a variable in a record. It is very convenient to write:</p>
|
||||
<pre wrap> ++record.foo;</pre>
|
||||
<p wrap>Rather than:</p>
|
||||
<pre wrap> int temp(record.foo);
|
||||
++temp;
|
||||
record.foo = temp;</pre>
|
||||
<h2><a name="Design">Design</a> considerations for Boost.Endian types</h2>
|
||||
<ul>
|
||||
<li>Must be suitable for I/O - in other words, must be memcpyable.</li>
|
||||
<li>Must provide exactly the size and internal byte ordering specified.</li>
|
||||
<li>Must work correctly when the internal integer representation has more bits
|
||||
that the sum of the bits in the external byte representation. Sign extension
|
||||
must work correctly when the internal integer representation type has more
|
||||
bits than the sum of the bits in the external bytes. For example, using
|
||||
a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for
|
||||
both positive and negative values.</li>
|
||||
<li>Must work correctly (including using the same defined external
|
||||
representation) regardless of whether a compiler treats char as signed or
|
||||
unsigned.</li>
|
||||
<li>Unaligned types must not cause compilers to insert padding bytes.</li>
|
||||
<li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian
|
||||
integers often become pessimizations when changing
|
||||
machines or compilers. Pessimizations can also happen when changing compiler switches,
|
||||
compiler versions, or CPU models of the same architecture.</li>
|
||||
</ul>
|
||||
<h2><a name="Experience">Experience</a></h2>
|
||||
<p>Classes with similar functionality have been independently developed by
|
||||
several Boost programmers and used very successful in high-value, high-use
|
||||
applications for many years. These independently developed endian libraries
|
||||
often evolved from C libraries that were also widely used. Endian types have proven widely useful across a wide
|
||||
range of computer architectures and applications.</p>
|
||||
<h2><a name="Motivating-use-cases">Motivating use cases</a></h2>
|
||||
<p>Neil Mayhew writes: "I can also provide a meaningful use-case for this
|
||||
library: reading TrueType font files from disk and processing the contents. The
|
||||
data format has fixed endianness (big) and has unaligned values in various
|
||||
places. Using Boost.Endian simplifies and cleans the code wonderfully."</p>
|
||||
<h2><a name="C++0x">C++11</a></h2>
|
||||
<p>The availability of the C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a> feature is detected automatically, and will be used if
|
||||
present to ensure that objects of <code>class endian</code> are trivial, and
|
||||
thus POD's.</p>
|
||||
<h2><a name="Compilation">Compilation</a></h2>
|
||||
<p>Boost.Endian is implemented entirely within headers, with no need to link to
|
||||
any Boost object libraries.</p>
|
||||
<p>Several macros allow user control over features:</p>
|
||||
<ul>
|
||||
<li>BOOST_ENDIAN_NO_CTORS causes <code>class endian</code> to have no
|
||||
constructors. The intended use is for compiling user code that must be
|
||||
portable between compilers regardless of C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a> support. Use of constructors will always fail, <br>
|
||||
</li>
|
||||
<li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if
|
||||
the compiler does not support C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a>. This is ensures that , and so can be used in unions.
|
||||
In C++11, <code>class endian</code> objects are POD's even though they have
|
||||
constructors.</li>
|
||||
</ul>
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
<p>Original design developed by Darin Adler based on classes developed by Mark
|
||||
Borgerding. Four original class templates combined into a single <code>endian</code>
|
||||
class template by Beman Dawes, who put the library together, provided
|
||||
documentation, added the typedefs, and also added the <code>unrolled_byte_loops</code>
|
||||
sign partial specialization to correctly extend the sign when cover integer size
|
||||
differs from endian representation size. Vicente Botet and other reviewers
|
||||
suggested supporting floating point types.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38642" --></p>
|
||||
<p>© Copyright Beman Dawes, 2006-2009, 2013</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,75 +0,0 @@
|
||||
Conversion function naming bikeshed
|
||||
|
||||
return-by-value modify-argument
|
||||
------------------ ---------------
|
||||
|
||||
reverse_endianness reverse_endianness_in_place
|
||||
" reverse_endianness_arg
|
||||
endian_reverse endian_reverse_in_place
|
||||
" endian_reverse_inplace
|
||||
" endian_reverse_replace
|
||||
" endian_reverse_in_situ
|
||||
" endian_reverse_here
|
||||
" endian_reverse_this
|
||||
" endian_reverse_self
|
||||
" endian_reverse_arg
|
||||
" endian_reverse_in
|
||||
|
||||
reverse reverse_in_place
|
||||
reverse_endian reverse_endian_in_place
|
||||
|
||||
swap_endianness swap_endianness_in_place
|
||||
swap_endian swap_endian_in_place
|
||||
endian_swap endian_swap_this
|
||||
|
||||
flip_endianness flip_endianness_in_place
|
||||
flip_endian flip_endian_in_place
|
||||
endian_flip endian_flip_in_place
|
||||
|
||||
|
||||
reverse_order reverse_order_in_place
|
||||
|
||||
|
||||
Key points:
|
||||
|
||||
* The above names are defined in a user namespace as customization points to be found by
|
||||
ADL, and so cannot depend on the enclosing namespace name to signal readers that they
|
||||
are related to endianness.
|
||||
* The above functions are rarely called directly by user code, which is more likely to use
|
||||
the various conditional functions instead. So explicitness is more important than
|
||||
brevity.
|
||||
|
||||
Conditional names
|
||||
|
||||
big_to_native native_to_big little_to_native native_to_little
|
||||
|
||||
big_to_host host_to_big
|
||||
|
||||
be_to_ne ne_to_be
|
||||
|
||||
from_big, to_big
|
||||
|
||||
big_to_native big_to_native
|
||||
native_to_big native_to_big
|
||||
|
||||
conditional_reverse runtime_conditional_reverse
|
||||
conditional_reverse conditional_reverse <------
|
||||
|
||||
merriam-webster.com/dictionary
|
||||
|
||||
reverse [1] (adjective): opposite or contrary to a previous or normal condition <reverse order>
|
||||
reverse [2] (verb) : to change (something) to an opposite state or condition
|
||||
|
||||
swap (verb) : to give something to someone and receive something in return : to trade or exchange (things)
|
||||
|
||||
flip (verb)
|
||||
|
||||
: to turn (something) over by throwing it up in the air with a quick movement
|
||||
|
||||
: to cause (something) to turn or turn over quickly
|
||||
|
||||
: to move (something) with a quick light movement
|
||||
|
||||
|
||||
|
||||
|
627
doc/buffers.html
627
doc/buffers.html
@ -1,627 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Endian Buffer Types</title>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="../../../index.html">
|
||||
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86"></a></td>
|
||||
<td align="middle">
|
||||
<b>
|
||||
<font size="6">Endian Buffer Types</font> </b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
|
||||
<tr>
|
||||
<td><b><a href="../../../index.htm">Boost Home</a>
|
||||
<a href="index.html">Endian Home</a>
|
||||
<a href="conversion.html">Conversion Functions</a>
|
||||
<a href="arithmetic.html">Arithmetic Types</a>
|
||||
<a href="buffers.html">Buffer Types</a></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<i><b>Contents</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Example">Example</a><br>
|
||||
<a href="#Limitations">Limitations</a><br>
|
||||
<a href="#Feature-set">Feature set</a><br>
|
||||
<a href="#Types">Enums and typedefs</a><br>
|
||||
<a href="#Class_template_endian">Class template <code>endian_buffer</code></a><br>
|
||||
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Members">Members</a><br>
|
||||
<a href="#FAQ">FAQ</a><br>
|
||||
<a href="#Design">Design</a><br>
|
||||
<a href="#C++0x">C++11</a><br>
|
||||
<a href="#Compilation">Compilation</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<b><i>Headers</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<p dir="ltr">
|
||||
<a href="../include/boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
||||
<a href="../include/boost/endian/buffers.hpp"><boost/endian/buffers.hpp></a><br>
|
||||
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>The internal byte order of arithmetic types is traditionally called <b><i>endianness</i></b>. See the
|
||||
<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for
|
||||
a full
|
||||
exploration of <b><i>endianness</i></b>, including definitions of <i><b>big
|
||||
endian</b></i> and <i><b>little endian</b></i>.</p>
|
||||
<p>Header <a href="buffers.html">boost/endian/buffers.hpp</a>
|
||||
provides <code>endian_buffer</code>, a portable endian integer and floating-point binary buffer
|
||||
class template with control over
|
||||
byte order, value type, size, and alignment independent of the platform's native
|
||||
endianness. Typedefs provide easy-to-use names
|
||||
for common configurations.</p>
|
||||
<p>Use cases primarily involve data portability, either via files or network
|
||||
connections, but these byte-holders may
|
||||
also be used to reduce memory use, file size, or network activity since they
|
||||
|
||||
provide binary numeric sizes not otherwise available.</p>
|
||||
<p dir="ltr">Class <code>endian_buffer</code> is aimed at users who wish
|
||||
explicit control over when endianness conversions occur. It also serves as the
|
||||
base class for the <code><a href="arithmetic.html">endian_arithmetic</a></code>
|
||||
class template, which is aimed at users who wish fully automatic endianness
|
||||
conversion and direct support for all normal arithmetic operations.</p>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a
|
||||
binary file containing four byte big-endian and little-endian integers:</p>
|
||||
<blockquote>
|
||||
<pre>#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format. Why the designer
|
||||
// decided to mix big and little endians in the same file is not known. But
|
||||
// this is a real-world format and users wishing to write low level code
|
||||
// manipulating these files have to deal with the mixed endianness.
|
||||
|
||||
struct header
|
||||
{
|
||||
big_int32_<code>buf_</code>t file_code;
|
||||
big_int32_<code>buf_</code>t file_length;
|
||||
little_int32_<code>buf_</code>t version;
|
||||
little_int32_<code>buf_</code>t shape_type;
|
||||
};
|
||||
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
|
||||
|
||||
header h;
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof(header);
|
||||
h.version = 1;
|
||||
h.shape_type = 0x01020304;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes
|
||||
// used for binary file operations when ultimate efficiency is important. Such
|
||||
// I/O is often performed in some C++ wrapper class, but to drive home the
|
||||
// point that endian integers are often used in fairly low-level code that does
|
||||
// bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
|
||||
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>After compiling and executing <a href="../example/endian_example.cpp">endian_example.cpp</a>,
|
||||
a hex dump of <code>test.dat</code> shows:</p>
|
||||
<blockquote>
|
||||
<pre>01020304 00000010 01000000 04030201</pre>
|
||||
</blockquote>
|
||||
<p>Notice that the first two 32-bit integers are big endian while the second two
|
||||
are little endian, even though the machine this was compiled and run on was
|
||||
little endian.</p>
|
||||
<h2><a name="Limitations">Limitations</a></h2>
|
||||
<p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code>
|
||||
is some other value, compilation will result in an <code>#error</code>. This
|
||||
restriction is in place because the design, implementation, testing, and
|
||||
documentation has only considered issues related to 8-bit bytes, and there have
|
||||
been no real-world use cases presented for other sizes.</p>
|
||||
<p>In C++03, <code>endian_buffer</code> does not meet the requirements for POD types
|
||||
because it has constructors, private data members, and a base class. This means
|
||||
that common use cases are relying on unspecified behavior in that the C++
|
||||
Standard does not guarantee memory layout for non-POD types. This has not been a
|
||||
problem in practice since all known C++ compilers do layout memory as if <code>
|
||||
endian</code> were a POD type. In C++11, it is possible to specify the
|
||||
default constructor as trivial, and private data members and base classes will
|
||||
no longer disqualify a type from being a POD. Thus under C++11, <code>endian_buffer</code>
|
||||
will no longer be relying on unspecified behavior.</p>
|
||||
<h2><a name="Feature-set">Feature set</a></h2>
|
||||
<ul>
|
||||
<li>Big endian| little endian | native endian byte ordering.</li>
|
||||
<li>Signed | unsigned</li>
|
||||
<li>Unaligned | aligned</li>
|
||||
<li>Integer | floating point</li>
|
||||
<li>1-8 byte (unaligned) | 2, 4, 8 byte (aligned)</li>
|
||||
<li>Choice of value type</li>
|
||||
</ul>
|
||||
<h2>Enums and t<a name="Types">ypedefs</a></h2>
|
||||
<p>Two scoped enums are provided:</p>
|
||||
<blockquote>
|
||||
<pre>enum class order {big, little, native};
|
||||
|
||||
enum class align {no, yes}; </pre>
|
||||
</blockquote>
|
||||
<p>One class template is provided:</p>
|
||||
<blockquote>
|
||||
<pre>template <order Order, typename T, std::size_t Nbits, align A = align::no>
|
||||
class endian_buffer;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Typedefs, such as <code>big_int32_buf_t</code>, provide convenient naming
|
||||
conventions for common use cases:</p>
|
||||
<blockquote>
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%">
|
||||
<tr>
|
||||
<td width="18%" align="center"><b><i>Name</i></b></td>
|
||||
<td width="10%" align="center"><b><i>Endianness</i></b></td>
|
||||
<td width="10%" align="center"><b><i>Sign</i></b></td>
|
||||
<td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td>
|
||||
<td width="49%" align="center"><b><i>Alignment</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_int</code><i><b>n</b></i><code>_buf_t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_int</code><b><i>n</i></b><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>big</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>little</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="10%" align="center">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
|
||||
<td width="10%" align="center"><code>native</code></td>
|
||||
<td width="10%" align="center">signed</td>
|
||||
<td width="15%">32,64</td>
|
||||
<td width="49%" align="center"><code>no</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
</blockquote>
|
||||
<p>The unaligned types do not cause compilers to insert padding bytes in classes
|
||||
and structs. This is an important characteristic that can be exploited to minimize wasted space in
|
||||
memory, files, and network transmissions. </p>
|
||||
<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF">
|
||||
Code that uses a</span>ligned types is possibly non-portable because alignment
|
||||
requirements vary between hardware architectures and because alignment may be
|
||||
affected by compiler switches or pragmas. For example, alignment of an 64-bit
|
||||
integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types
|
||||
are only available on architectures with 16, 32, and 64-bit integer types. </p>
|
||||
<p><b><i>Note:</i></b> One-byte types
|
||||
have identical
|
||||
functionality. They are provided to improve code readability and searchability.</p>
|
||||
<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_buffer</code></h2>
|
||||
<p>An <code>endian_buffer</code> is an integer byte-holder with user-specified <a href="#endianness">
|
||||
endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The
|
||||
usual operations on integers are supplied.</p>
|
||||
<h3><a name="Synopsis">Synopsis</a></h3>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
// C++11 features emulated if not available
|
||||
|
||||
enum class <a name="order">order</a>
|
||||
{
|
||||
big, // big-endian
|
||||
little, // little-endian
|
||||
native = <b><i>implementation-defined</i></b> // same as order::big or order::little<b><i>
|
||||
</i></b>};
|
||||
|
||||
enum class <a name="alignment">align</a> {no, yes};
|
||||
|
||||
template <order Order, class T, std::size_t Nbits, align Align = align::no>
|
||||
class endian_buffer
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
<a href="#endian">endian_buffer</a>() noexcept = default;
|
||||
explicit <a href="#explicit-endian">endian_buffer</a>(T v) noexcept;
|
||||
|
||||
endian_buffer& <a href="#operator-eq">operator=</a>(T v) noexcept;
|
||||
value_type <a href="#value">value</a>() const noexcept;
|
||||
const char* <a href="#data">data</a>() const noexcept;
|
||||
protected:
|
||||
<b><i>implementaton-defined</i></b> endian_value; // for exposition only
|
||||
};
|
||||
|
||||
// typedefs
|
||||
|
||||
// aligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_t;
|
||||
typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_t;
|
||||
|
||||
// aligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_t;
|
||||
typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_t;
|
||||
|
||||
// unaligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_ut;
|
||||
typedef endian_buffer<order::big, double, 64, align::no> big_float64_buf_ut;
|
||||
|
||||
// unaligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32, align::no> little_float32_buf_ut;
|
||||
typedef endian_buffer<order::little, double, 64, align::no> little_float64_buf_ut;
|
||||
|
||||
// aligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_t;
|
||||
typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_t;
|
||||
typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_t;
|
||||
|
||||
// aligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_t;
|
||||
typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_t;
|
||||
typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_t;
|
||||
|
||||
// aligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_t;
|
||||
typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_t;
|
||||
typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_t;
|
||||
|
||||
// aligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_t;
|
||||
typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_t;
|
||||
typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_t;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
// unaligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_ut;
|
||||
|
||||
// unaligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_ut;
|
||||
|
||||
// unaligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_ut;
|
||||
|
||||
// unaligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_ut;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef <b><i>implementation-defined</i></b>_int8_buf_ut native_int8_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int16_buf_ut native_int16_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int24_buf_ut native_int24_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int32_buf_ut native_int32_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int40_buf_ut native_int40_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int48_buf_ut native_int48_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int56_buf_ut native_int56_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_int64_buf_ut native_int64_buf_ut;
|
||||
|
||||
// unaligned native endian unsigned integer types
|
||||
typedef <b><i>implementation-defined</i></b>_uint8_buf_ut native_uint8_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint16_buf_ut native_uint16_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint24_buf_ut native_uint24_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint32_buf_ut native_uint32_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint40_buf_ut native_uint40_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint48_buf_ut native_uint48_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint56_buf_ut native_uint56_buf_ut;
|
||||
typedef <b><i>implementation-defined</i></b>_uint64_buf_ut native_uint64_buf_ut;
|
||||
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost</pre>
|
||||
<p>The <i><b><code>implementation-defined</code></b></i> text in typedefs above is either
|
||||
<code>big</code> or <code>little</code> according to the native endianness of the
|
||||
platform.</p>
|
||||
<p>The expository data member <code>endian_value</code> stores the current value
|
||||
of an <code>endian_value</code> object as a sequence of bytes ordered as
|
||||
specified by the <code>Order</code> template parameter. The <i><b><code>
|
||||
implementation-defined</code></b></i> type of <code>endian_value</code> is a
|
||||
type such as <code><span style="font-size: 85%">char[Nbits/CHAR_BIT]</span></code>
|
||||
or <code><span style="font-size: 85%">T</span></code> that meets the
|
||||
requirements imposed by the <code>Nbits</code> and <code>Align</code> template
|
||||
parameters. The <code><span style="font-size: 85%">CHAR_BIT</span></code>
|
||||
macro is defined in <code><span style="font-size: 85%"><climits></span></code>.
|
||||
The only value of <code><span style="font-size: 85%">CHAR_BIT</span></code> that
|
||||
is required to be supported is 8.</p>
|
||||
<p>Template parameter <code><span style="font-size: 85%">T</span></code> is
|
||||
required to be a standard integer type (C++std, 3.9.1) and <code>
|
||||
<span style="font-size: 85%">sizeof(T)*CHAR_BIT</span></code> is required to be
|
||||
greater or equal to <span style="font-size: 85%"> <code>Nbits</code>.</span></p>
|
||||
<h3><a name="Members">Members</a></h3>
|
||||
<pre><code><a name="endian">endian</a>_buffer() noexcept = default;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of type <code>endian_buffer<Order, T,
|
||||
Nbits, Align></code>.</p>
|
||||
</blockquote>
|
||||
<pre><code>explicit <a name="explicit-endian">endian</a>_buffer(T v) noexcept;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of type <code>endian_buffer<Order, T,
|
||||
Nbits, Align></code>.</p>
|
||||
<p><i>Postcondition:</i> <code>value() == v & mask</code>, where <code>mask</code>
|
||||
is a constant of type <code>value_type</code> with <code>Nbits</code> low-order
|
||||
bits set to one.</p>
|
||||
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
|
||||
endianness conversion if required is performed by <code>
|
||||
boost::endian::endian_reverse</code>.</p>
|
||||
</blockquote>
|
||||
<pre><code>endian_buffer& <a name="operator-eq">operator=</a>(T v) noexcept;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Postcondition:</i> <code>value() == v & mask</code>, where <code>mask</code>
|
||||
is a constant of type <code>value_type</code> with <code>Nbits</code>
|
||||
low-order bits set to one..</p>
|
||||
<p><i>Returns:</i> <code>*this</code>.</p>
|
||||
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
|
||||
endianness conversion if required is performed by <code>
|
||||
boost::endian::endian_reverse</code>.</p>
|
||||
</blockquote>
|
||||
<pre>value_type <a name="value">value</a>()<code> const noexcept;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>endian_value</code>, converted to <code>value_type</code>
|
||||
if necessary and having the endianness of the native platform.</p>
|
||||
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
|
||||
endianness conversion if required is performed by <code>
|
||||
boost::endian::endian_reverse</code>.</p>
|
||||
</blockquote>
|
||||
<pre><code>const char* <a name="data">data</a>() const noexcept;</code></pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> A pointer to the first byte of <code>endian_value</code>.</p>
|
||||
</blockquote>
|
||||
<h2><a name="FAQ">FAQ</a></h2>
|
||||
|
||||
<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide
|
||||
FAQ.</p>
|
||||
|
||||
<p><b>Why not just use Boost.Serialization?</b> Serialization involves a
|
||||
conversion for every object involved in I/O. Endian integers require no
|
||||
conversion or copying. They are already in the desired format for binary I/O.
|
||||
Thus they can be read or written in bulk.</p>
|
||||
<p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several
|
||||
<a href="#Compilation">macros</a> are available to force PODness in all cases.</p>
|
||||
<p><b>What are the implications of endian integer types not being POD's with C++03
|
||||
compilers?</b> They
|
||||
can't be used in unions. Also, compilers aren't required to align or lay
|
||||
out storage in portable ways, although this potential problem hasn't prevented
|
||||
use of Boost.Endian with
|
||||
real compilers.</p>
|
||||
<p><b>What good is <i>native </i>endianness?</b> It provides alignment and
|
||||
size guarantees not available from the built-in types. It eases generic
|
||||
programming.</p>
|
||||
<p><b>Why bother with the aligned endian types?</b> Aligned integer operations
|
||||
may be faster (as much as 10 to 20 times faster) if the endianness and alignment of
|
||||
the type matches the endianness and alignment requirements of the machine. The code,
|
||||
however, is
|
||||
likely to be somewhat less portable than with the unaligned types.</p>
|
||||
<p><b>Why provide the arithmetic operations?</b> Providing a full set of operations reduces program
|
||||
clutter and makes code both easier to write and to read. Consider
|
||||
incrementing a variable in a record. It is very convenient to write:</p>
|
||||
<pre wrap> ++record.foo;</pre>
|
||||
<p wrap>Rather than:</p>
|
||||
<pre wrap> int temp(record.foo);
|
||||
++temp;
|
||||
record.foo = temp;</pre>
|
||||
<h2><a name="Design">Design</a> considerations for Boost.Endian buffers</h2>
|
||||
<ul>
|
||||
<li>Must be suitable for I/O - in other words, must be memcpyable.</li>
|
||||
<li>Must provide exactly the size and internal byte ordering specified.</li>
|
||||
<li>Must work correctly when the internal integer representation has more bits
|
||||
that the sum of the bits in the external byte representation. Sign extension
|
||||
must work correctly when the internal integer representation type has more
|
||||
bits than the sum of the bits in the external bytes. For example, using
|
||||
a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for
|
||||
both positive and negative values.</li>
|
||||
<li>Must work correctly (including using the same defined external
|
||||
representation) regardless of whether a compiler treats char as signed or
|
||||
unsigned.</li>
|
||||
<li>Unaligned types must not cause compilers to insert padding bytes.</li>
|
||||
<li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian
|
||||
integers often become pessimizations when changing
|
||||
machines or compilers. Pessimizations can also happen when changing compiler switches,
|
||||
compiler versions, or CPU models of the same architecture.</li>
|
||||
</ul>
|
||||
<h2><a name="C++0x">C++11</a></h2>
|
||||
<p>The availability of the C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a> feature is detected automatically, and will be used if
|
||||
present to ensure that objects of <code>class endian</code> are trivial, and
|
||||
thus POD's.</p>
|
||||
<h2><a name="Compilation">Compilation</a></h2>
|
||||
<p>Boost.Endian is implemented entirely within headers, with no need to link to
|
||||
any Boost object libraries.</p>
|
||||
<p>Several macros allow user control over features:</p>
|
||||
<ul>
|
||||
<li>BOOST_ENDIAN_NO_CTORS causes <code>class endian</code> to have no
|
||||
constructors. The intended use is for compiling user code that must be
|
||||
portable between compilers regardless of C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a> support. Use of constructors will always fail, <br>
|
||||
</li>
|
||||
<li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if
|
||||
the compiler does not support C++11
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
|
||||
Defaulted Functions</a>. This is ensures that , and so can be used in unions.
|
||||
In C++11, <code>class endian</code> objects are POD's even though they have
|
||||
constructors.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->06 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38644" --></p>
|
||||
<p>© Copyright Beman Dawes, 2006-2009, 2013</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,385 +0,0 @@
|
||||
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
<title>Endian Conversion Functions</title>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="../../../index.html">
|
||||
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86" ></a></td>
|
||||
<td align="middle">
|
||||
<b>
|
||||
<font size="6">Endian Conversion Functions</font></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
|
||||
<tr>
|
||||
<td><b><a href="../../../index.htm">Boost Home</a>
|
||||
<a href="index.html">Endian Home</a>
|
||||
<a href="conversion.html">Conversion Functions</a>
|
||||
<a href="arithmetic.html">Arithmetic Types</a>
|
||||
<a href="buffers.html">Buffer Types</a></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<i><b>Contents</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Reference">Reference</a><br>
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Requirements">Requirements</a><br>
|
||||
<code><a href="#EndianReversible">EndianReversible</a></code><br>
|
||||
<a href="#Customization-points">Customization for
|
||||
UDTs</a><br>
|
||||
<a href="#Functions">Functions</a><br>
|
||||
<a href="#FAQ">FAQ</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<b><i>Headers</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="../include/boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
||||
<a href="../include/boost/endian/buffers.hpp"><boost/endian/buffers.hpp></a><br>
|
||||
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
|
||||
<p>Header <a href="../include/boost/endian/conversion.hpp">boost/endian/conversion.hpp</a>
|
||||
provides byte order reversal and conversion functions that convert objects of
|
||||
the built-in
|
||||
integer types, and also types <code>float</code> and <code>double,</code>
|
||||
between native, big, or little endian byte
|
||||
ordering. User defined types are also supported.</p>
|
||||
|
||||
<h2><a name="Reference">Reference</a></h2>
|
||||
|
||||
<p>Functions are implemented <code>inline</code> if appropriate.<code> noexcept</code> is
|
||||
elided for compilers that do not support it.
|
||||
Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.</p>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h3>
|
||||
Header <code><boost/endian/conversion.hpp></code>
|
||||
<a name="Synopsis">Synopsis</a></h3>
|
||||
|
||||
<pre>#define BOOST_ENDIAN_INTRINSIC_MSG "<b><font face="Arial"><i>message describing presence or absence of intrinsics</i></font></b>"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
enum class <a name="order">order</a>
|
||||
{
|
||||
big, // big endian
|
||||
little, // little endian
|
||||
native = <b><i>implementation-defined-as-big-or-little
|
||||
</i></b>};
|
||||
|
||||
int8_t <a href="#endian_reverse">endian_reverse</a>(int8_t x) noexcept;
|
||||
int16_t <a href="#endian_reverse">endian_reverse</a>(int16_t x) noexcept;
|
||||
int32_t <a href="#endian_reverse">endian_reverse</a>(int32_t x) noexcept;
|
||||
int64_t <a href="#endian_reverse">endian_reverse</a>(int64_t x) noexcept;
|
||||
uint8_t <a href="#endian_reverse">endian_reverse</a>(uint8_t x) noexcept;
|
||||
uint16_t <a href="#endian_reverse">endian_reverse</a>(uint16_t x) noexcept;
|
||||
uint32_t <a href="#endian_reverse">endian_reverse</a>(uint32_t x) noexcept;
|
||||
uint64_t <a href="#endian_reverse">endian_reverse</a>(uint64_t x) noexcept;
|
||||
float <a href="#endian_reverse">endian_reverse</a>(float x) noexcept;
|
||||
double <a href="#endian_reverse">endian_reverse</a>(double x) noexcept;
|
||||
|
||||
template <class EndianReversible>
|
||||
EndianReversible big_to_native(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_big(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible little_to_native(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_little(EndianReversible x) noexcept;
|
||||
template <order O1, order O2, class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x,
|
||||
order order1, order order2) noexcept;
|
||||
|
||||
template <class EndianReversible>
|
||||
void endian_reverse_inplace(EndianReversible& x) noexcept;
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
void big_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_big_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void little_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_little_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <order O1, order O2, class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x,
|
||||
order order1, order order2) noexcept;
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost</pre>
|
||||
<p dir="ltr">The implementation is required to define the <code>enum class order</code>
|
||||
constant <code>native</code> as
|
||||
<code>big</code> on big endian platforms and <code>little</code> on little
|
||||
endian platforms.</p>
|
||||
<h3 dir="ltr"><a name="Definitions">Definitions</a></h3>
|
||||
<p dir="ltr">The standard integral types (C++std 3.9.1) except <code>bool</code>,
|
||||
and the floating point types <code>float</code> and <code>double</code> are
|
||||
collectively called the <i>endian types</i>.</p>
|
||||
<h3><a name="Requirements">Requirements</a></h3>
|
||||
<h4><a name="Template-argument-requirements">Template argument requirements</a></h4>
|
||||
<p dir="ltr">The template definitions in the <code>boost/endian/conversion.hpp</code>
|
||||
header refer to various named requirements whose details are set out in the
|
||||
tables in this subsection. In these tables, <code>T</code> is an object or
|
||||
reference type to be supplied by a C++ program instantiating a template; <code>x</code>
|
||||
is a value of type (possibly <code>const</code>) <code>T</code>; <code>mlx</code> is a
|
||||
modifiable lvalue of type <code>T</code>.</p>
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3" align="center"><b><code><a name="EndianReversible">EndianReversible</a></code></b>
|
||||
requirements (in addition to <b><code>CopyConstructible</code></b>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Return<br>
|
||||
type</b></td>
|
||||
<td><b>Requirements</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>endian_reverse(x)</code></td>
|
||||
<td align="center" valign="top"><code>T</code></td>
|
||||
<td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is
|
||||
an endian type, returns the value of <code>x</code> with the order of bytes
|
||||
reversed.</p>
|
||||
<p>If <code>T</code> is an class type, the function:</p>
|
||||
<ul>
|
||||
<li>Returns the value of <code>x</code>
|
||||
with the order of bytes reversed for all data members of types or arrays of
|
||||
types that meet the <code>EndianReversible</code> requirements, and;</li>
|
||||
<li>Is a non-member function in the same namespace as <code>T</code> that
|
||||
can be found by argument dependent lookup (ADL). </li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p> </p>
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="2" align="center"><b><code><a name="EndianReversibleInplace">EndianReversibleInplace</a></code></b>
|
||||
requirements (in addition to <b><code>CopyConstructible</code></b>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Requirements</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>endian_reverse_inplace(mlx)</code></td>
|
||||
<td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is
|
||||
an endian type, reverses the order of bytes in <code>mlx</code>.</p>
|
||||
<p>If <code>T</code> is an class type, the function:</p>
|
||||
<ul>
|
||||
<li>Reverses the order of bytes of all data members of <code>mlx</code>
|
||||
that have types or arrays of
|
||||
types that meet the <code>EndianReversible</code> or <code>EndianReversibleInplace</code>
|
||||
requirements, and;</li>
|
||||
<li>Is a non-member function in the same namespace as <code>T</code> that
|
||||
can be found by argument dependent lookup (ADL). </li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> [<i>Note:</i> Because there is a function template for <code>endian_reverse_inplace</code>
|
||||
that calls <code>endian_reverse</code>, only <code>endian_reverse</code>
|
||||
is required for a user-defined type to meet the <code>EndianReversibleInplace</code>
|
||||
requirements. Although User-defined types are not required to supply an <code>endian_reverse_inplace</code>
|
||||
function, doing so may improved efficiency. <i> —end note</i>]</p>
|
||||
|
||||
<h4> <a name="Customization-points">Customization points</a> for user-defined types (<a name="UDT">UDT</a>s)</h4>
|
||||
|
||||
<p> This subsection describes requirements on the Endian library's implementation.</p>
|
||||
|
||||
<p> The library's function templates requiring <code>
|
||||
<a href="#EndianReversible">EndianReversible</a></code> are
|
||||
required to perform reversal of endianness if needed by making an unqualified
|
||||
call to <code>endian_reverse()</code>.</p>
|
||||
|
||||
<p> The library's function templates requiring <code>
|
||||
<a href="#EndianReversibleInplace">EndianReversibleInplace</a></code> are required to perform reversal of endianness if needed by making an
|
||||
unqualified call to <code>endian_reverse_inplace()</code>.</p>
|
||||
|
||||
<p> See <a href="../example/udt_conversion_example.cpp">
|
||||
udt_conversion_example.cpp</a> for an example user-defined type.</p>
|
||||
|
||||
<h3><a name="Functions">Functions</a></h3>
|
||||
<pre><a name="endian_reverse"></a>int8_t endian_reverse(int8_t x) noexcept;
|
||||
int16_t endian_reverse(int16_t x) noexcept;
|
||||
int32_t endian_reverse(int32_t x) noexcept;
|
||||
int64_t endian_reverse(int64_t x) noexcept;
|
||||
uint8_t endian_reverse(uint8_t x) noexcept;
|
||||
uint16_t endian_reverse(uint16_t x) noexcept;
|
||||
uint32_t endian_reverse(uint32_t x) noexcept;
|
||||
uint64_t endian_reverse(uint64_t x) noexcept;
|
||||
float endian_reverse(float x) noexcept;
|
||||
double endian_reverse(double x) noexcept;</pre>
|
||||
<blockquote>
|
||||
<p dir="ltr"><i>Returns:</i> <i><code>x</code></i>, with the order of its
|
||||
constituent bytes reversed.</p>
|
||||
<p><i>Remarks:</i> Meet the <code>EndianReversible</code> requirements.</p>
|
||||
<p>[<i>Note:</i> The Boost.Endian library does not provide overloads for the C++ standard library
|
||||
supplied types. <i>—end note</i>]</p>
|
||||
</blockquote>
|
||||
|
||||
<pre>template <class EndianReversible>
|
||||
EndianReversible big_to_native(EndianReversible x) noexcept;</pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
<i>Returns:</i> <code>conditional_reverse<order::big,
|
||||
order::native>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversible>
|
||||
EndianReversible native_to_big(EndianReversible x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>conditional_reverse<order::native, order::big>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversible>
|
||||
EndianReversible little_to_native(EndianReversible x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>conditional_reverse<order::little, order::native>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversible>
|
||||
EndianReversible native_to_little(EndianReversible x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>conditional_reverse<order::native, order::little>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <order O1, order O2, class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>x</code> if <code>O1 == O2,</code> otherwise
|
||||
<code>endian_reverse(x)</code>.</p>
|
||||
<p><i>Remarks: </i>Whether <code>x</code> or <code>endian_reverse(x)</code>
|
||||
is to be returned shall be determined at compile time.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x,
|
||||
order order1, order order2) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Returns:</i> <code>order1 == order2 ? x : endian_reverse(x)</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<pre>template <class EndianReversible>
|
||||
void endian_reverse_inplace(EndianReversible& x) noexcept; </pre>
|
||||
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> <code>x</code> <code>= endian_reverse(x)</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
<pre>template <class EndianReversibleInplace>
|
||||
void big_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
<i>Effects:</i> <code>conditional_reverse_inplace<order::big,
|
||||
order::native>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversibleInplace>
|
||||
void native_to_big_inplace(EndianReversibleInplace& x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
<i>Effects:</i> <code>conditional_reverse_inplace<order::native,
|
||||
order::big>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversibleInplace>
|
||||
void little_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
<i>Effects:</i> <code>conditional_reverse_inplace<order::little, order::native>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversibleInplace>
|
||||
void native_to_little_inplace(EndianReversibleInplace& x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
<i>Effects:</i> <code>conditional_reverse_inplace<order::native,
|
||||
order::little>(x)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>template <order O1, order O2, class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; </pre>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> None if <code>O1 == O2,</code> otherwise
|
||||
<code>endian_reverse_inplace(x)</code>.</p>
|
||||
<p><i>Remarks: </i>Which effect applies shall be determined at compile time.</p>
|
||||
</blockquote>
|
||||
<pre>template <class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x,
|
||||
order order1, order order2) noexcept; </pre>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<p><i>Effects: </i>If <code>order1 == order2</code> then <code>endian_reverse_inplace(x)</code>.</p>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h2> <a name="FAQ">FAQ</a></h2>
|
||||
|
||||
<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide
|
||||
FAQ.</p>
|
||||
|
||||
<p><b>Why are both value returning and modify-in-place functions provided?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>Returning the result by value is the standard C and C++ idiom for functions that compute a
|
||||
value from an argument. Modify-in-place functions allow cleaner code in many real-world
|
||||
endian use cases and are more efficient for user-defined types that have
|
||||
members such as string data that do not need to be reversed. Thus both forms are
|
||||
provided.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p><b>Why are 8, 16, 32, and 64-bit integers supported rather than the built-in
|
||||
char, short, int, long, long long, etc?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>The primary use case, portable file or network data, needs these de facto
|
||||
standard sizes. Using types that vary with the platform would greatly limit
|
||||
portability for both programs and data.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2><p>Tomas Puverle was instrumental in identifying and articulating the need to
|
||||
support endian conversion as separate from endian integer types. Phil Endecott suggested the form of the value returning signatures. Vicente Botet and other reviewers suggested supporting floating point types and user defined types. General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by several reviewers, and by David Stone, who provided his Boost licensed macro implementation that became the starting point for <a href="../include/boost/endian/detail/intrinsic.hpp">boost/endian/detail/intrinsic.hpp</a>.
|
||||
Pierre Talbot provided the <code>int8_t endian_reverse()</code> and templated
|
||||
<code>endian_reverse_inplace()</code> implementations.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->11 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38635" --></p>
|
||||
<p>© Copyright Beman Dawes, 2011, 2013</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
7
doc/endian-docinfo-footer.html
Normal file
7
doc/endian-docinfo-footer.html
Normal file
@ -0,0 +1,7 @@
|
||||
<style>
|
||||
|
||||
*:not(pre)>code { background: none; color: #600000; }
|
||||
:not(pre):not([class^=L])>code { background: none; color: #600000; }
|
||||
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
|
||||
|
||||
</style>
|
39
doc/endian.adoc
Normal file
39
doc/endian.adoc
Normal file
@ -0,0 +1,39 @@
|
||||
////
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
# Boost.Endian: The Boost Endian Library
|
||||
Beman Dawes
|
||||
:toc: left
|
||||
:toclevels: 2
|
||||
:idprefix:
|
||||
:listing-caption: Code Example
|
||||
:docinfo: private-footer
|
||||
:source-highlighter: rouge
|
||||
:source-language: c++
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
include::endian/overview.adoc[]
|
||||
include::endian/changelog.adoc[]
|
||||
include::endian/choosing_approach.adoc[]
|
||||
include::endian/conversion.adoc[]
|
||||
include::endian/buffers.adoc[]
|
||||
include::endian/arithmetic.adoc[]
|
||||
include::endian/history.adoc[]
|
||||
|
||||
:leveloffset: -1
|
||||
|
||||
[appendix]
|
||||
## Copyright and License
|
||||
|
||||
This documentation is
|
||||
|
||||
* Copyright 2011-2016 Beman Dawes
|
||||
* Copyright 2019 Peter Dimov
|
||||
|
||||
and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
|
616
doc/endian/arithmetic.adoc
Normal file
616
doc/endian/arithmetic.adoc
Normal file
@ -0,0 +1,616 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#arithmetic]
|
||||
# Endian Arithmetic Types
|
||||
:idprefix: arithmetic_
|
||||
|
||||
## Introduction
|
||||
|
||||
Header `boost/endian/arithmetic.hpp` provides integer binary types with
|
||||
control over byte order, value type, size, and alignment. Typedefs provide
|
||||
easy-to-use names for common configurations.
|
||||
|
||||
These types provide portable byte-holders for integer data, independent of
|
||||
particular computer architectures. Use cases almost always involve I/O, either
|
||||
via files or network connections. Although data portability is the primary
|
||||
motivation, these integer byte-holders may also be used to reduce memory use,
|
||||
file size, or network activity since they provide binary integer sizes not
|
||||
otherwise available.
|
||||
|
||||
Such integer byte-holder types are traditionally called *endian* types. See the
|
||||
http://en.wikipedia.org/wiki/Endian[Wikipedia] for a full exploration of
|
||||
*endianness*, including definitions of *big endian* and *little endian*.
|
||||
|
||||
Boost endian integers provide the same full set of {cpp} assignment, arithmetic,
|
||||
and relational operators as {cpp} standard integral types, with the standard
|
||||
semantics.
|
||||
|
||||
Unary arithmetic operators are `+`, `-`, `~`, `!`, plus both prefix and postfix
|
||||
`--` and `++`. Binary arithmetic operators are `+`, `+=`, `-`, `-=`, `\*`,
|
||||
``*=``, `/`, `/=`, `&`, `&=`, `|`, `|=`, `^`, `^=`, `<<`, `<\<=`, `>>`, and
|
||||
`>>=`. Binary relational operators are `==`, `!=`, `<`, `\<=`, `>`, and `>=`.
|
||||
|
||||
Implicit conversion to the underlying value type is provided. An implicit
|
||||
constructor converting from the underlying value type is provided.
|
||||
|
||||
## Example
|
||||
|
||||
The `endian_example.cpp` program writes a binary file containing four-byte,
|
||||
big-endian and little-endian integers:
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format.
|
||||
// Why the designer decided to mix big and little endians in
|
||||
// the same file is not known. But this is a real-world format
|
||||
// and users wishing to write low level code manipulating these
|
||||
// files have to deal with the mixed endianness.
|
||||
|
||||
struct header
|
||||
{
|
||||
big_int32_t file_code;
|
||||
big_int32_t file_length;
|
||||
little_int32_t version;
|
||||
little_int32_t shape_type;
|
||||
};
|
||||
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
header h;
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof(header);
|
||||
h.version = 1;
|
||||
h.shape_type = 0x01020304;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio>
|
||||
// fread/fwrite is sometimes used for binary file operations
|
||||
// when ultimate efficiency is important. Such I/O is often
|
||||
// performed in some C++ wrapper class, but to drive home the
|
||||
// point that endian integers are often used in fairly
|
||||
// low-level code that does bulk I/O operations, <cstdio>
|
||||
// fopen/fwrite is used for I/O in this example.
|
||||
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi) != 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
After compiling and executing `endian_example.cpp`, a hex dump of `test.dat`
|
||||
shows:
|
||||
|
||||
```
|
||||
01020304 00000010 01000000 04030201
|
||||
```
|
||||
|
||||
Notice that the first two 32-bit integers are big endian while the second two
|
||||
are little endian, even though the machine this was compiled and run on was
|
||||
little endian.
|
||||
|
||||
## Limitations
|
||||
|
||||
Requires `<climits>`, `CHAR_BIT == 8`. If `CHAR_BIT` is some other value,
|
||||
compilation will result in an `#error`. This restriction is in place because the
|
||||
design, implementation, testing, and documentation has only considered issues
|
||||
related to 8-bit bytes, and there have been no real-world use cases presented
|
||||
for other sizes.
|
||||
|
||||
In {cpp}03, `endian_arithmetic` does not meet the requirements for POD types
|
||||
because it has constructors, private data members, and a base class. This means
|
||||
that common use cases are relying on unspecified behavior in that the {cpp}
|
||||
Standard does not guarantee memory layout for non-POD types. This has not been a
|
||||
problem in practice since all known {cpp} compilers lay out memory as if
|
||||
`endian` were a POD type. In {cpp}11, it is possible to specify the default
|
||||
constructor as trivial, and private data members and base classes no longer
|
||||
disqualify a type from being a POD type. Thus under {cpp}11, `endian_arithmetic`
|
||||
will no longer be relying on unspecified behavior.
|
||||
|
||||
## Feature set
|
||||
|
||||
* Big endian| little endian | native endian byte ordering.
|
||||
* Signed | unsigned
|
||||
* Unaligned | aligned
|
||||
* 1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)
|
||||
* Choice of value type
|
||||
|
||||
## Enums and typedefs
|
||||
|
||||
Two scoped enums are provided:
|
||||
|
||||
```
|
||||
enum class order { big, little, native };
|
||||
|
||||
enum class align { no, yes };
|
||||
```
|
||||
|
||||
One class template is provided:
|
||||
|
||||
```
|
||||
template <order Order, typename T, std::size_t n_bits,
|
||||
align Align = align::no>
|
||||
class endian_arithmetic;
|
||||
```
|
||||
|
||||
Typedefs, such as `big_int32_t`, provide convenient naming conventions for
|
||||
common use cases:
|
||||
|
||||
[%header,cols=5*]
|
||||
|===
|
||||
|Name |Alignment |Endianness |Sign |Sizes in bits (n)
|
||||
|`big_intN_t` |no |big |signed |8,16,24,32,40,48,56,64
|
||||
|`big_uintN_t` |no |big |unsigned |8,16,24,32,40,48,56,64
|
||||
|`little_intN_t` |no |little |signed |8,16,24,32,40,48,56,64
|
||||
|`little_uintN_t` |no |little |unsigned |8,16,24,32,40,48,56,64
|
||||
|`native_intN_t` |no |native |signed |8,16,24,32,40,48,56,64
|
||||
|`native_uintN_t` |no |native |unsigned |8,16,24,32,40,48,56,64
|
||||
|`big_intN_at` |yes |big |signed |8,16,32,64
|
||||
|`big_uintN_at` |yes |big |unsigned |8,16,32,64
|
||||
|`little_intN_at` |yes |little |signed |8,16,32,64
|
||||
|`little_uintN_at` |yes |little |unsigned |8,16,32,64
|
||||
|===
|
||||
|
||||
The unaligned types do not cause compilers to insert padding bytes in classes
|
||||
and structs. This is an important characteristic that can be exploited to
|
||||
minimize wasted space in memory, files, and network transmissions.
|
||||
|
||||
CAUTION: Code that uses aligned types is possibly non-portable because
|
||||
alignment requirements vary between hardware architectures and because
|
||||
alignment may be affected by compiler switches or pragmas. For example,
|
||||
alignment of an 64-bit integer may be to a 32-bit boundary on a 32-bit machine.
|
||||
Furthermore, aligned types are only available on architectures with 8, 16, 32,
|
||||
and 64-bit integer types.
|
||||
|
||||
TIP: Prefer unaligned arithmetic types.
|
||||
|
||||
TIP: Protect yourself against alignment ills. For example:
|
||||
[none]
|
||||
{blank}::
|
||||
+
|
||||
```
|
||||
static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong");
|
||||
```
|
||||
|
||||
NOTE: One-byte arithmetic types have identical layout on all platforms, so they
|
||||
never actually reverse endianness. They are provided to enable generic code,
|
||||
and to improve code readability and searchability.
|
||||
|
||||
## Class template `endian_arithmetic`
|
||||
|
||||
`endian_arithmetic` is an integer byte-holder with user-specified endianness,
|
||||
value type, size, and alignment. The usual operations on arithmetic types are
|
||||
supplied.
|
||||
|
||||
### Synopsis
|
||||
|
||||
```
|
||||
#include <boost/endian/buffers.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
// C++11 features emulated if not available
|
||||
|
||||
enum class align { no, yes };
|
||||
|
||||
template <order Order, class T, std::size_t n_bits,
|
||||
align Align = align::no>
|
||||
class endian_arithmetic
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
// if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 PODs are not
|
||||
// available then these two constructors will not be present
|
||||
endian_arithmetic() noexcept = default;
|
||||
endian_arithmetic(T v) noexcept;
|
||||
|
||||
endian_arithmetic& operator=(T v) noexcept;
|
||||
operator value_type() const noexcept;
|
||||
value_type value() const noexcept;
|
||||
unsigned char* data() noexcept;
|
||||
unsigned char const* data() const noexcept;
|
||||
|
||||
// arithmetic operations
|
||||
// note that additional operations are provided by the value_type
|
||||
value_type operator+() const noexcept;
|
||||
endian_arithmetic& operator+=(value_type y) noexcept;
|
||||
endian_arithmetic& operator-=(value_type y) noexcept;
|
||||
endian_arithmetic& operator*=(value_type y) noexcept;
|
||||
endian_arithmetic& operator/=(value_type y) noexcept;
|
||||
endian_arithmetic& operator%=(value_type y) noexcept;
|
||||
endian_arithmetic& operator&=(value_type y) noexcept;
|
||||
endian_arithmetic& operator|=(value_type y) noexcept;
|
||||
endian_arithmetic& operator^=(value_type y) noexcept;
|
||||
endian_arithmetic& operator<<=(value_type y) noexcept;
|
||||
endian_arithmetic& operator>>=(value_type y) noexcept;
|
||||
endian_arithmetic& operator++() noexcept;
|
||||
endian_arithmetic& operator--() noexcept;
|
||||
endian_arithmetic operator++(int) noexcept;
|
||||
endian_arithmetic operator--(int) noexcept;
|
||||
|
||||
// Stream inserter
|
||||
template <class charT, class traits>
|
||||
friend std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const endian_arithmetic& x);
|
||||
|
||||
// Stream extractor
|
||||
template <class charT, class traits>
|
||||
friend std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, endian_arithmetic& x);
|
||||
};
|
||||
|
||||
// typedefs
|
||||
|
||||
// unaligned big endian signed integer types
|
||||
typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t;
|
||||
typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t;
|
||||
|
||||
// unaligned big endian unsigned integer types
|
||||
typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t;
|
||||
typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t;
|
||||
|
||||
// unaligned big endian floating point types
|
||||
typedef endian_arithmetic<order::big, float, 32> big_float32_t;
|
||||
typedef endian_arithmetic<order::big, double, 64> big_float64_t;
|
||||
|
||||
// unaligned little endian signed integer types
|
||||
typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t;
|
||||
typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t;
|
||||
|
||||
// unaligned little endian unsigned integer types
|
||||
typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t;
|
||||
typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t;
|
||||
|
||||
// unaligned little endian floating point types
|
||||
typedef endian_arithmetic<order::little, float, 32> little_float32_t;
|
||||
typedef endian_arithmetic<order::little, double, 64> little_float64_t;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef endian_arithmetic<order::native, int_least8_t, 8> native_int8_t;
|
||||
typedef endian_arithmetic<order::native, int_least16_t, 16> native_int16_t;
|
||||
typedef endian_arithmetic<order::native, int_least32_t, 24> native_int24_t;
|
||||
typedef endian_arithmetic<order::native, int_least32_t, 32> native_int32_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 40> native_int40_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 48> native_int48_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 56> native_int56_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 64> native_int64_t;
|
||||
|
||||
// unaligned native endian unsigned integer types
|
||||
typedef endian_arithmetic<order::native, uint_least8_t, 8> native_uint8_t;
|
||||
typedef endian_arithmetic<order::native, uint_least16_t, 16> native_uint16_t;
|
||||
typedef endian_arithmetic<order::native, uint_least32_t, 24> native_uint24_t;
|
||||
typedef endian_arithmetic<order::native, uint_least32_t, 32> native_uint32_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 40> native_uint40_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 48> native_uint48_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 56> native_uint56_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 64> native_uint64_t;
|
||||
|
||||
// unaligned native endian floating point types
|
||||
typedef endian_arithmetic<order::native, float, 32> native_float32_t;
|
||||
typedef endian_arithmetic<order::native, double, 64> native_float64_t;
|
||||
|
||||
// aligned big endian signed integer types
|
||||
typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at;
|
||||
typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at;
|
||||
typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at;
|
||||
typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at;
|
||||
|
||||
// aligned big endian unsigned integer types
|
||||
typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at;
|
||||
typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at;
|
||||
typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at;
|
||||
typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at;
|
||||
|
||||
// aligned big endian floating point types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::yes> big_float32_at;
|
||||
typedef endian_arithmetic<order::big, double, 64, align::yes> big_float64_at;
|
||||
|
||||
// aligned little endian signed integer types
|
||||
typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at;
|
||||
typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at;
|
||||
typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at;
|
||||
typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at;
|
||||
|
||||
// aligned little endian unsigned integer types
|
||||
typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at;
|
||||
typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at;
|
||||
typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at;
|
||||
typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at;
|
||||
|
||||
// aligned little endian floating point types
|
||||
typedef endian_arithmetic<order::little, float, 32, align::yes> little_float32_at;
|
||||
typedef endian_arithmetic<order::little, double, 64, align::yes> little_float64_at;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for that use case
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
The only supported value of `CHAR_BIT` is 8.
|
||||
|
||||
The valid values of `Nbits` are as follows:
|
||||
|
||||
* When `sizeof(T)` is 1, `Nbits` shall be 8;
|
||||
* When `sizeof(T)` is 2, `Nbits` shall be 16;
|
||||
* When `sizeof(T)` is 4, `Nbits` shall be 24 or 32;
|
||||
* When `sizeof(T)` is 8, `Nbits` shall be 40, 48, 56, or 64.
|
||||
|
||||
Other values of `sizeof(T)` are not supported.
|
||||
|
||||
When `Nbits` is equal to `sizeof(T)*8`, `T` must be a standard arithmetic type.
|
||||
|
||||
When `Nbits` is less than `sizeof(T)*8`, `T` must be a standard integral type
|
||||
({cpp}std, [basic.fundamental]) that is not `bool`.
|
||||
|
||||
### Members
|
||||
|
||||
```
|
||||
endian_arithmetic() noexcept = default; // C++03: endian(){}
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs an uninitialized object.
|
||||
|
||||
```
|
||||
endian_arithmetic(T v) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: See `endian_buffer::endian_buffer(T)`.
|
||||
|
||||
```
|
||||
endian_arithmetic& operator=(T v) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: See `endian_buffer::operator=(T)`.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
value_type value() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: See `endian_buffer::value()`.
|
||||
|
||||
```
|
||||
unsigned char* data() noexcept;
|
||||
```
|
||||
```
|
||||
unsigned char const* data() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: See `endian_buffer::data()`.
|
||||
|
||||
```
|
||||
operator T() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns::
|
||||
`value()`.
|
||||
|
||||
### Other operators
|
||||
|
||||
Other operators on endian objects are forwarded to the equivalent operator on
|
||||
`value_type`.
|
||||
|
||||
### Stream inserter
|
||||
|
||||
```
|
||||
template <class charT, class traits>
|
||||
friend std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const endian_arithmetic& x);
|
||||
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `os << +x`.
|
||||
[none]
|
||||
|
||||
### Stream extractor
|
||||
|
||||
```
|
||||
template <class charT, class traits>
|
||||
friend std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, endian_arithmetic& x);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: As if:
|
||||
+
|
||||
```
|
||||
T i;
|
||||
if (is >> i)
|
||||
x = i;
|
||||
```
|
||||
Returns:: `is`.
|
||||
|
||||
## FAQ
|
||||
|
||||
See the <<overview_faq,Overview FAQ>> for a library-wide FAQ.
|
||||
|
||||
Why not just use Boost.Serialization?::
|
||||
Serialization involves a conversion for every object involved in I/O. Endian
|
||||
integers require no conversion or copying. They are already in the desired
|
||||
format for binary I/O. Thus they can be read or written in bulk.
|
||||
|
||||
Are endian types PODs?::
|
||||
Yes for {cpp}11. No for {cpp}03, although several
|
||||
<<arithmetic_compilation,macros>> are available to force PODness in all cases.
|
||||
|
||||
What are the implications of endian integer types not being PODs with {cpp}03 compilers?::
|
||||
They can't be used in unions. Also, compilers aren't required to align or lay
|
||||
out storage in portable ways, although this potential problem hasn't prevented
|
||||
use of Boost.Endian with real compilers.
|
||||
|
||||
What good is native endianness?::
|
||||
It provides alignment and size guarantees not available from the built-in
|
||||
types. It eases generic programming.
|
||||
|
||||
Why bother with the aligned endian types?::
|
||||
Aligned integer operations may be faster (as much as 10 to 20 times faster)
|
||||
if the endianness and alignment of the type matches the endianness and
|
||||
alignment requirements of the machine. The code, however, will be somewhat less
|
||||
portable than with the unaligned types.
|
||||
|
||||
Why provide the arithmetic operations?::
|
||||
Providing a full set of operations reduces program clutter and makes code
|
||||
both easier to write and to read. Consider incrementing a variable in a record.
|
||||
It is very convenient to write:
|
||||
+
|
||||
```
|
||||
++record.foo;
|
||||
```
|
||||
+
|
||||
Rather than:
|
||||
+
|
||||
```
|
||||
int temp(record.foo);
|
||||
++temp;
|
||||
record.foo = temp;
|
||||
```
|
||||
|
||||
## Design considerations for Boost.Endian types
|
||||
|
||||
* Must be suitable for I/O - in other words, must be memcpyable.
|
||||
* Must provide exactly the size and internal byte ordering specified.
|
||||
* Must work correctly when the internal integer representation has more bits
|
||||
that the sum of the bits in the external byte representation. Sign extension
|
||||
must work correctly when the internal integer representation type has more
|
||||
bits than the sum of the bits in the external bytes. For example, using
|
||||
a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for
|
||||
both positive and negative values.
|
||||
* Must work correctly (including using the same defined external
|
||||
representation) regardless of whether a compiler treats char as signed or
|
||||
unsigned.
|
||||
* Unaligned types must not cause compilers to insert padding bytes.
|
||||
* The implementation should supply optimizations with great care. Experience
|
||||
has shown that optimizations of endian integers often become pessimizations
|
||||
when changing machines or compilers. Pessimizations can also happen when
|
||||
changing compiler switches, compiler versions, or CPU models of the same
|
||||
architecture.
|
||||
|
||||
## Experience
|
||||
|
||||
Classes with similar functionality have been independently developed by
|
||||
several Boost programmers and used very successful in high-value, high-use
|
||||
applications for many years. These independently developed endian libraries
|
||||
often evolved from C libraries that were also widely used. Endian types have
|
||||
proven widely useful across a wide range of computer architectures and
|
||||
applications.
|
||||
|
||||
## Motivating use cases
|
||||
|
||||
Neil Mayhew writes: "I can also provide a meaningful use-case for this
|
||||
library: reading TrueType font files from disk and processing the contents. The
|
||||
data format has fixed endianness (big) and has unaligned values in various
|
||||
places. Using Boost.Endian simplifies and cleans the code wonderfully."
|
||||
|
||||
## {cpp}11
|
||||
|
||||
The availability of the {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions] feature is detected automatically, and will be used if present to
|
||||
ensure that objects of `class endian_arithmetic` are trivial, and thus PODs.
|
||||
|
||||
## Compilation
|
||||
|
||||
Boost.Endian is implemented entirely within headers, with no need to link to any
|
||||
Boost object libraries.
|
||||
|
||||
Several macros allow user control over features:
|
||||
|
||||
* BOOST_ENDIAN_NO_CTORS causes `class endian_arithmetic` to have no
|
||||
constructors. The intended use is for compiling user code that must be portable
|
||||
between compilers regardless of {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions] support. Use of constructors will always fail,
|
||||
* BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if
|
||||
the compiler does not support {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions]. This is ensures that objects of `class endian_arithmetic` are PODs,
|
||||
and so can be used in {cpp}03 unions. In {cpp}11, `class endian_arithmetic`
|
||||
objects are PODs, even though they have constructors, so can always be used in
|
||||
unions.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Original design developed by Darin Adler based on classes developed by Mark
|
||||
Borgerding. Four original class templates combined into a single
|
||||
`endian_arithmetic` class template by Beman Dawes, who put the library together,
|
||||
provided documentation, added the typedefs, and also added the
|
||||
`unrolled_byte_loops` sign partial specialization to correctly extend the sign
|
||||
when cover integer size differs from endian representation size.
|
541
doc/endian/buffers.adoc
Normal file
541
doc/endian/buffers.adoc
Normal file
@ -0,0 +1,541 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#buffers]
|
||||
# Endian Buffer Types
|
||||
:idprefix: buffers_
|
||||
|
||||
## Introduction
|
||||
|
||||
The internal byte order of arithmetic types is traditionally called
|
||||
*endianness*. See the http://en.wikipedia.org/wiki/Endian[Wikipedia] for a full
|
||||
exploration of *endianness*, including definitions of *big endian* and *little
|
||||
endian*.
|
||||
|
||||
Header `boost/endian/buffers.hpp` provides `endian_buffer`, a portable endian
|
||||
integer binary buffer class template with control over byte order, value type,
|
||||
size, and alignment independent of the platform's native endianness. Typedefs
|
||||
provide easy-to-use names for common configurations.
|
||||
|
||||
Use cases primarily involve data portability, either via files or network
|
||||
connections, but these byte-holders may also be used to reduce memory use, file
|
||||
size, or network activity since they provide binary numeric sizes not otherwise
|
||||
available.
|
||||
|
||||
Class `endian_buffer` is aimed at users who wish explicit control over when
|
||||
endianness conversions occur. It also serves as the base class for the
|
||||
<<arithmetic,endian_arithmetic>> class template, which is aimed at users who
|
||||
wish fully automatic endianness conversion and direct support for all normal
|
||||
arithmetic operations.
|
||||
|
||||
## Example
|
||||
|
||||
The `example/endian_example.cpp` program writes a binary file containing
|
||||
four-byte, big-endian and little-endian integers:
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <boost/endian/buffers.hpp> // see Synopsis below
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format.
|
||||
// Why the designer decided to mix big and little endians in
|
||||
// the same file is not known. But this is a real-world format
|
||||
// and users wishing to write low level code manipulating these
|
||||
// files have to deal with the mixed endianness.
|
||||
|
||||
struct header
|
||||
{
|
||||
big_int32_buf_t file_code;
|
||||
big_int32_buf_t file_length;
|
||||
little_int32_buf_t version;
|
||||
little_int32_buf_t shape_type;
|
||||
};
|
||||
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
header h;
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof(header);
|
||||
h.version = 1;
|
||||
h.shape_type = 0x01020304;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio>
|
||||
// fread/fwrite is sometimes used for binary file operations
|
||||
// when ultimate efficiency is important. Such I/O is often
|
||||
// performed in some C++ wrapper class, but to drive home the
|
||||
// point that endian integers are often used in fairly
|
||||
// low-level code that does bulk I/O operations, <cstdio>
|
||||
// fopen/fwrite is used for I/O in this example.
|
||||
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi) != 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
After compiling and executing `example/endian_example.cpp`, a hex dump of
|
||||
`test.dat` shows:
|
||||
|
||||
```
|
||||
01020304 00000010 01000000 04030201
|
||||
```
|
||||
|
||||
Notice that the first two 32-bit integers are big endian while the second two
|
||||
are little endian, even though the machine this was compiled and run on was
|
||||
little endian.
|
||||
|
||||
## Limitations
|
||||
|
||||
Requires `<climits>`, `CHAR_BIT == 8`. If `CHAR_BIT` is some other value,
|
||||
compilation will result in an `#error`. This restriction is in place because the
|
||||
design, implementation, testing, and documentation has only considered issues
|
||||
related to 8-bit bytes, and there have been no real-world use cases presented
|
||||
for other sizes.
|
||||
|
||||
In {cpp}03, `endian_buffer` does not meet the requirements for POD types because
|
||||
it has constructors and a private data member. This means that
|
||||
common use cases are relying on unspecified behavior in that the {cpp} Standard
|
||||
does not guarantee memory layout for non-POD types. This has not been a problem
|
||||
in practice since all known {cpp} compilers lay out memory as if `endian` were
|
||||
a POD type. In {cpp}11, it is possible to specify the default constructor as
|
||||
trivial, and private data members and base classes no longer disqualify a type
|
||||
from being a POD type. Thus under {cpp}11, `endian_buffer` will no longer be
|
||||
relying on unspecified behavior.
|
||||
|
||||
## Feature set
|
||||
|
||||
* Big endian| little endian | native endian byte ordering.
|
||||
* Signed | unsigned
|
||||
* Unaligned | aligned
|
||||
* 1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)
|
||||
* Choice of value type
|
||||
|
||||
## Enums and typedefs
|
||||
|
||||
Two scoped enums are provided:
|
||||
|
||||
```
|
||||
enum class order { big, little, native };
|
||||
|
||||
enum class align { no, yes };
|
||||
```
|
||||
|
||||
One class template is provided:
|
||||
|
||||
```
|
||||
template <order Order, typename T, std::size_t Nbits,
|
||||
align Align = align::no>
|
||||
class endian_buffer;
|
||||
```
|
||||
|
||||
Typedefs, such as `big_int32_buf_t`, provide convenient naming conventions for
|
||||
common use cases:
|
||||
|
||||
[%header,cols=5*]
|
||||
|===
|
||||
|Name |Alignment |Endianness |Sign |Sizes in bits (n)
|
||||
|`big_intN_buf_t` |no |big |signed |8,16,24,32,40,48,56,64
|
||||
|`big_uintN_buf_t` |no |big |unsigned |8,16,24,32,40,48,56,64
|
||||
|`little_intN_buf_t` |no |little |signed |8,16,24,32,40,48,56,64
|
||||
|`little_uintN_buf_t` |no |little |unsigned |8,16,24,32,40,48,56,64
|
||||
|`native_intN_buf_t` |no |native |signed |8,16,24,32,40,48,56,64
|
||||
|`native_uintN_buf_t` |no |native |unsigned |8,16,24,32,40,48,56,64
|
||||
|`big_intN_buf_at` |yes |big |signed |8,16,32,64
|
||||
|`big_uintN_buf_at` |yes |big |unsigned |8,16,32,64
|
||||
|`little_intN_buf_at` |yes |little |signed |8,16,32,64
|
||||
|`little_uintN_buf_at` |yes |little |unsigned |8,16,32,64
|
||||
|===
|
||||
|
||||
The unaligned types do not cause compilers to insert padding bytes in classes
|
||||
and structs. This is an important characteristic that can be exploited to
|
||||
minimize wasted space in memory, files, and network transmissions.
|
||||
|
||||
CAUTION: Code that uses aligned types is possibly non-portable because alignment
|
||||
requirements vary between hardware architectures and because alignment may be
|
||||
affected by compiler switches or pragmas. For example, alignment of an 64-bit
|
||||
integer may be to a 32-bit boundary on a 32-bit machine and to a 64-bit boundary
|
||||
on a 64-bit machine. Furthermore, aligned types are only available on
|
||||
architectures with 8, 16, 32, and 64-bit integer types.
|
||||
|
||||
TIP: Prefer unaligned buffer types.
|
||||
|
||||
TIP: Protect yourself against alignment ills. For example:
|
||||
[none]
|
||||
{blank}::
|
||||
+
|
||||
```
|
||||
static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong");
|
||||
```
|
||||
|
||||
Note: One-byte big and little buffer types have identical layout on all
|
||||
platforms, so they never actually reverse endianness. They are provided to
|
||||
enable generic code, and to improve code readability and searchability.
|
||||
|
||||
## Class template `endian_buffer`
|
||||
|
||||
An `endian_buffer` is a byte-holder for arithmetic types with
|
||||
user-specified endianness, value type, size, and alignment.
|
||||
|
||||
### Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
// C++11 features emulated if not available
|
||||
|
||||
enum class align { no, yes };
|
||||
|
||||
template <order Order, class T, std::size_t Nbits,
|
||||
align Align = align::no>
|
||||
class endian_buffer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
endian_buffer() noexcept = default;
|
||||
explicit endian_buffer(T v) noexcept;
|
||||
|
||||
endian_buffer& operator=(T v) noexcept;
|
||||
value_type value() const noexcept;
|
||||
unsigned char* data() noexcept;
|
||||
unsigned char const* data() const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
unsigned char value_[Nbits / CHAR_BIT]; // exposition only
|
||||
};
|
||||
|
||||
// stream inserter
|
||||
template <class charT, class traits, order Order, class T,
|
||||
std::size_t n_bits, align Align>
|
||||
std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os,
|
||||
const endian_buffer<Order, T, n_bits, Align>& x);
|
||||
|
||||
// stream extractor
|
||||
template <class charT, class traits, order Order, class T,
|
||||
std::size_t n_bits, align A>
|
||||
std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is,
|
||||
endian_buffer<Order, T, n_bits, Align>& x);
|
||||
|
||||
// typedefs
|
||||
|
||||
// unaligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
|
||||
typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
|
||||
typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
|
||||
typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;
|
||||
|
||||
// unaligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;
|
||||
|
||||
// unaligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32> big_float32_buf_t;
|
||||
typedef endian_buffer<order::big, double, 64> big_float64_buf_t;
|
||||
|
||||
// unaligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
|
||||
typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
|
||||
typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
|
||||
typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;
|
||||
|
||||
// unaligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;
|
||||
|
||||
// unaligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32> little_float32_buf_t;
|
||||
typedef endian_buffer<order::little, double, 64> little_float64_buf_t;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef endian_buffer<order::native, int_least8_t, 8> native_int8_buf_t;
|
||||
typedef endian_buffer<order::native, int_least16_t, 16> native_int16_buf_t;
|
||||
typedef endian_buffer<order::native, int_least32_t, 24> native_int24_buf_t;
|
||||
typedef endian_buffer<order::native, int_least32_t, 32> native_int32_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 40> native_int40_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 48> native_int48_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 56> native_int56_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 64> native_int64_buf_t;
|
||||
|
||||
// unaligned native endian unsigned integer types
|
||||
typedef endian_buffer<order::native, uint_least8_t, 8> native_uint8_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least16_t, 16> native_uint16_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least32_t, 24> native_uint24_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least32_t, 32> native_uint32_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 40> native_uint40_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 48> native_uint48_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 56> native_uint56_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 64> native_uint64_buf_t;
|
||||
|
||||
// unaligned native endian floating point types
|
||||
typedef endian_buffer<order::native, float, 32> native_float32_buf_t;
|
||||
typedef endian_buffer<order::native, double, 64> native_float64_buf_t;
|
||||
|
||||
// aligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
|
||||
typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
|
||||
typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
|
||||
typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;
|
||||
|
||||
// aligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
|
||||
typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
|
||||
typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
|
||||
typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;
|
||||
|
||||
// aligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_at;
|
||||
typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_at;
|
||||
|
||||
// aligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
|
||||
typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at;
|
||||
typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at;
|
||||
typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at;
|
||||
|
||||
// aligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at;
|
||||
typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;
|
||||
typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;
|
||||
typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;
|
||||
|
||||
// aligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_at;
|
||||
typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_at;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
The expository data member `value_` stores the current value of the
|
||||
`endian_buffer` object as a sequence of bytes ordered as specified by the
|
||||
`Order` template parameter. The `CHAR_BIT` macro is defined in `<climits>`.
|
||||
The only supported value of `CHAR_BIT` is 8.
|
||||
|
||||
The valid values of `Nbits` are as follows:
|
||||
|
||||
* When `sizeof(T)` is 1, `Nbits` shall be 8;
|
||||
* When `sizeof(T)` is 2, `Nbits` shall be 16;
|
||||
* When `sizeof(T)` is 4, `Nbits` shall be 24 or 32;
|
||||
* When `sizeof(T)` is 8, `Nbits` shall be 40, 48, 56, or 64.
|
||||
|
||||
Other values of `sizeof(T)` are not supported.
|
||||
|
||||
When `Nbits` is equal to `sizeof(T)*8`, `T` must be a trivially copyable type
|
||||
(such as `float`) that is assumed to have the same endianness as `uintNbits_t`.
|
||||
|
||||
When `Nbits` is less than `sizeof(T)*8`, `T` must be either a standard integral
|
||||
type ({cpp}std, [basic.fundamental]) or an `enum`.
|
||||
|
||||
### Members
|
||||
|
||||
```
|
||||
endian_buffer() noexcept = default;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Constructs an uninitialized object.
|
||||
|
||||
```
|
||||
explicit endian_buffer(T v) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `endian_store<T, Nbits/8, Order>( value_, v )`.
|
||||
|
||||
```
|
||||
endian_buffer& operator=(T v) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `endian_store<T, Nbits/8, Order>( value_, v )`.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
value_type value() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `endian_load<T, Nbits/8, Order>( value_ )`.
|
||||
|
||||
```
|
||||
unsigned char* data() noexcept;
|
||||
```
|
||||
```
|
||||
unsigned char const* data() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns::
|
||||
A pointer to the first byte of `value_`.
|
||||
|
||||
### Non-member functions
|
||||
|
||||
```
|
||||
template <class charT, class traits, order Order, class T,
|
||||
std::size_t n_bits, align Align>
|
||||
std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os,
|
||||
const endian_buffer<Order, T, n_bits, Align>& x);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `os << x.value()`.
|
||||
|
||||
```
|
||||
template <class charT, class traits, order Order, class T,
|
||||
std::size_t n_bits, align A>
|
||||
std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is,
|
||||
endian_buffer<Order, T, n_bits, Align>& x);
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: As if:
|
||||
+
|
||||
```
|
||||
T i;
|
||||
if (is >> i)
|
||||
x = i;
|
||||
```
|
||||
Returns:: `is`.
|
||||
|
||||
## FAQ
|
||||
|
||||
See the <<overview_faq,Overview FAQ>> for a library-wide FAQ.
|
||||
|
||||
Why not just use Boost.Serialization?::
|
||||
Serialization involves a conversion for every object involved in I/O. Endian
|
||||
integers require no conversion or copying. They are already in the desired
|
||||
format for binary I/O. Thus they can be read or written in bulk.
|
||||
|
||||
Are endian types PODs?::
|
||||
Yes for {cpp}11. No for {cpp}03, although several
|
||||
<<buffers_compilation,macros>> are available to force PODness in all cases.
|
||||
|
||||
What are the implications of endian integer types not being PODs with {cpp}03 compilers?::
|
||||
They can't be used in unions. Also, compilers aren't required to align or lay
|
||||
out storage in portable ways, although this potential problem hasn't prevented
|
||||
use of Boost.Endian with real compilers.
|
||||
|
||||
What good is native endianness?::
|
||||
It provides alignment and size guarantees not available from the built-in
|
||||
types. It eases generic programming.
|
||||
|
||||
Why bother with the aligned endian types?::
|
||||
Aligned integer operations may be faster (as much as 10 to 20 times faster) if
|
||||
the endianness and alignment of the type matches the endianness and alignment
|
||||
requirements of the machine. The code, however, is likely to be somewhat less
|
||||
portable than with the unaligned types.
|
||||
|
||||
## Design considerations for Boost.Endian buffers
|
||||
|
||||
* Must be suitable for I/O - in other words, must be memcpyable.
|
||||
* Must provide exactly the size and internal byte ordering specified.
|
||||
* Must work correctly when the internal integer representation has more bits
|
||||
that the sum of the bits in the external byte representation. Sign extension
|
||||
must work correctly when the internal integer representation type has more
|
||||
bits than the sum of the bits in the external bytes. For example, using
|
||||
a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for
|
||||
both positive and negative values.
|
||||
* Must work correctly (including using the same defined external
|
||||
representation) regardless of whether a compiler treats char as signed or
|
||||
unsigned.
|
||||
* Unaligned types must not cause compilers to insert padding bytes.
|
||||
* The implementation should supply optimizations with great care. Experience
|
||||
has shown that optimizations of endian integers often become pessimizations
|
||||
when changing machines or compilers. Pessimizations can also happen when
|
||||
changing compiler switches, compiler versions, or CPU models of the same
|
||||
architecture.
|
||||
|
||||
## {cpp}11
|
||||
|
||||
The availability of the {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions] feature is detected automatically, and will be used if present to
|
||||
ensure that objects of `class endian_buffer` are trivial, and thus
|
||||
PODs.
|
||||
|
||||
## Compilation
|
||||
|
||||
Boost.Endian is implemented entirely within headers, with no need to link to
|
||||
any Boost object libraries.
|
||||
|
||||
Several macros allow user control over features:
|
||||
|
||||
* `BOOST_ENDIAN_NO_CTORS` causes `class endian_buffer` to have no
|
||||
constructors. The intended use is for compiling user code that must be
|
||||
portable between compilers regardless of {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions] support. Use of constructors will always fail,
|
||||
* `BOOST_ENDIAN_FORCE_PODNESS` causes `BOOST_ENDIAN_NO_CTORS` to be defined if
|
||||
the compiler does not support {cpp}11
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm[Defaulted
|
||||
Functions]. This is ensures that objects of `class endian_buffer` are PODs, and
|
||||
so can be used in {cpp}03 unions. In {cpp}11, `class endian_buffer` objects are
|
||||
PODs, even though they have constructors, so can always be used in unions.
|
41
doc/endian/changelog.adoc
Normal file
41
doc/endian/changelog.adoc
Normal file
@ -0,0 +1,41 @@
|
||||
////
|
||||
Copyright 2019 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#changelog]
|
||||
# Revision History
|
||||
|
||||
## Changes in 1.75.0
|
||||
|
||||
* `endian_arithmetic` no longer inherits from `endian_buffer`
|
||||
* When `BOOST_ENDIAN_NO_CTORS` is defined, the unaligned `endian_buffer` and
|
||||
`endian_arithmetic` are {cpp}03 PODs, to enable use of `++__attribute__((packed))++`
|
||||
|
||||
## Changes in 1.74.0
|
||||
|
||||
* Enabled scoped enumeration types in `endian_reverse`
|
||||
* Enabled `bool`, `enum`, `float`, `double` in `endian_reverse_inplace`
|
||||
* Added an overload of `endian_reverse_inplace` for arrays
|
||||
|
||||
## Changes in 1.72.0
|
||||
|
||||
* Made `endian_reverse`, `conditional_reverse` and `\*\_to_*` `constexpr`
|
||||
on GCC and Clang
|
||||
* Added convenience load and store functions
|
||||
* Added floating point convenience typedefs
|
||||
* Added a non-const overload of `data()`; changed its return type to `unsigned char*`
|
||||
* Added `__int128` support to `endian_reverse` when available
|
||||
* Added a convenience header `boost/endian.hpp`
|
||||
|
||||
## Changes in 1.71.0
|
||||
|
||||
* Clarified requirements on the value type template parameter
|
||||
* Added support for `float` and `double` to `endian_buffer` and `endian_arithmetic`
|
||||
* Added `endian_load`, `endian_store`
|
||||
* Updated `endian_reverse` to correctly support all non-`bool` integral types
|
||||
* Moved deprecated names to the deprecated header `endian.hpp`
|
314
doc/endian/choosing_approach.adoc
Normal file
314
doc/endian/choosing_approach.adoc
Normal file
@ -0,0 +1,314 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#choosing]
|
||||
# Choosing between Conversion Functions, Buffer Types, and Arithmetic Types
|
||||
:idprefix: choosing_
|
||||
|
||||
NOTE: Deciding which is the best endianness approach (conversion functions, buffer
|
||||
types, or arithmetic types) for a particular application involves complex
|
||||
engineering trade-offs. It is hard to assess those trade-offs without some
|
||||
understanding of the different interfaces, so you might want to read the
|
||||
<<conversion,conversion functions>>, <<buffers,buffer types>>, and
|
||||
<<arithmetic,arithmetic types>> pages before proceeding.
|
||||
|
||||
The best approach to endianness for a particular application depends on the
|
||||
interaction between the application's needs and the characteristics of each of
|
||||
the three approaches.
|
||||
|
||||
*Recommendation:* If you are new to endianness, uncertain, or don't want to
|
||||
invest the time to study engineering trade-offs, use
|
||||
<<arithmetic,endian arithmetic types>>. They are safe, easy to use, and easy to
|
||||
maintain. Use the _<<choosing_anticipating_need,anticipating need>>_ design
|
||||
pattern locally around performance hot spots like lengthy loops, if needed.
|
||||
|
||||
## Background
|
||||
|
||||
A dealing with endianness usually implies a program portability or a data
|
||||
portability requirement, and often both. That means real programs dealing with
|
||||
endianness are usually complex, so the examples shown here would really be
|
||||
written as multiple functions spread across multiple translation units. They
|
||||
would involve interfaces that can not be altered as they are supplied by
|
||||
third-parties or the standard library.
|
||||
|
||||
## Characteristics
|
||||
|
||||
The characteristics that differentiate the three approaches to endianness are
|
||||
the endianness invariants, conversion explicitness, arithmetic operations, sizes
|
||||
available, and alignment requirements.
|
||||
|
||||
### Endianness invariants
|
||||
|
||||
*Endian conversion functions* use objects of the ordinary {cpp} arithmetic types
|
||||
like `int` or `unsigned short` to hold values. That breaks the implicit
|
||||
invariant that the {cpp} language rules apply. The usual language rules only apply
|
||||
if the endianness of the object is currently set to the native endianness for
|
||||
the platform. That can make it very hard to reason about logic flow, and result
|
||||
in difficult to find bugs.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
struct data_t // big endian
|
||||
{
|
||||
int32_t v1; // description ...
|
||||
int32_t v2; // description ...
|
||||
... additional character data members (i.e. non-endian)
|
||||
int32_t v3; // description ...
|
||||
};
|
||||
|
||||
data_t data;
|
||||
|
||||
read(data);
|
||||
big_to_native_inplace(data.v1);
|
||||
big_to_native_inplace(data.v2);
|
||||
|
||||
...
|
||||
|
||||
++v1;
|
||||
third_party::func(data.v2);
|
||||
|
||||
...
|
||||
|
||||
native_to_big_inplace(data.v1);
|
||||
native_to_big_inplace(data.v2);
|
||||
write(data);
|
||||
```
|
||||
|
||||
The programmer didn't bother to convert `data.v3` to native endianness because
|
||||
that member isn't used. A later maintainer needs to pass `data.v3` to the
|
||||
third-party function, so adds `third_party::func(data.v3);` somewhere deep in
|
||||
the code. This causes a silent failure because the usual invariant that an
|
||||
object of type `int32_t` holds a value as described by the {cpp} core language
|
||||
does not apply.
|
||||
|
||||
*Endian buffer and arithmetic types* hold values internally as arrays of
|
||||
characters with an invariant that the endianness of the array never changes.
|
||||
That makes these types easier to use and programs easier to maintain.
|
||||
|
||||
Here is the same example, using an endian arithmetic type:
|
||||
|
||||
```
|
||||
struct data_t
|
||||
{
|
||||
big_int32_t v1; // description ...
|
||||
big_int32_t v2; // description ...
|
||||
... additional character data members (i.e. non-endian)
|
||||
big_int32_t v3; // description ...
|
||||
};
|
||||
|
||||
data_t data;
|
||||
|
||||
read(data);
|
||||
|
||||
...
|
||||
|
||||
++v1;
|
||||
third_party::func(data.v2);
|
||||
|
||||
...
|
||||
|
||||
write(data);
|
||||
```
|
||||
|
||||
A later maintainer can add `third_party::func(data.v3)` and it will just-work.
|
||||
|
||||
### Conversion explicitness
|
||||
|
||||
*Endian conversion functions* and *buffer types* never perform implicit
|
||||
conversions. This gives users explicit control of when conversion occurs, and
|
||||
may help avoid unnecessary conversions.
|
||||
|
||||
*Endian arithmetic types* perform conversion implicitly. That makes these types
|
||||
very easy to use, but can result in unnecessary conversions. Failure to hoist
|
||||
conversions out of inner loops can bring a performance penalty.
|
||||
|
||||
### Arithmetic operations
|
||||
|
||||
*Endian conversion functions* do not supply arithmetic operations, but this is
|
||||
not a concern since this approach uses ordinary {cpp} arithmetic types to hold
|
||||
values.
|
||||
|
||||
*Endian buffer types* do not supply arithmetic operations. Although this
|
||||
approach avoids unnecessary conversions, it can result in the introduction of
|
||||
additional variables and confuse maintenance programmers.
|
||||
|
||||
*Endian arithmetic types* do supply arithmetic operations. They are very easy to
|
||||
use if lots of arithmetic is involved.
|
||||
|
||||
### Sizes
|
||||
|
||||
*Endianness conversion functions* only support 1, 2, 4, and 8 byte integers.
|
||||
That's sufficient for many applications.
|
||||
|
||||
*Endian buffer and arithmetic types* support 1, 2, 3, 4, 5, 6, 7, and 8 byte
|
||||
integers. For an application where memory use or I/O speed is the limiting
|
||||
factor, using sizes tailored to application needs can be useful.
|
||||
|
||||
### Alignments
|
||||
|
||||
*Endianness conversion functions* only support aligned integer and
|
||||
floating-point types. That's sufficient for most applications.
|
||||
|
||||
*Endian buffer and arithmetic types* support both aligned and unaligned
|
||||
integer and floating-point types. Unaligned types are rarely needed, but when
|
||||
needed they are often very useful and workarounds are painful. For example:
|
||||
|
||||
Non-portable code like this:
|
||||
|
||||
```
|
||||
struct S {
|
||||
uint16_t a; // big endian
|
||||
uint32_t b; // big endian
|
||||
} __attribute__ ((packed));
|
||||
```
|
||||
|
||||
Can be replaced with portable code like this:
|
||||
|
||||
```
|
||||
struct S {
|
||||
big_uint16_ut a;
|
||||
big_uint32_ut b;
|
||||
};
|
||||
```
|
||||
|
||||
## Design patterns
|
||||
|
||||
Applications often traffic in endian data as records or packets containing
|
||||
multiple endian data elements. For simplicity, we will just call them records.
|
||||
|
||||
If desired endianness differs from native endianness, a conversion has to be
|
||||
performed. When should that conversion occur? Three design patterns have
|
||||
evolved.
|
||||
|
||||
### Convert only as needed (i.e. lazy)
|
||||
|
||||
This pattern defers conversion to the point in the code where the data
|
||||
element is actually used.
|
||||
|
||||
This pattern is appropriate when which endian element is actually used varies
|
||||
greatly according to record content or other circumstances
|
||||
|
||||
[#choosing_anticipating_need]
|
||||
### Convert in anticipation of need
|
||||
|
||||
This pattern performs conversion to native endianness in anticipation of use,
|
||||
such as immediately after reading records. If needed, conversion to the output
|
||||
endianness is performed after all possible needs have passed, such as just
|
||||
before writing records.
|
||||
|
||||
One implementation of this pattern is to create a proxy record with endianness
|
||||
converted to native in a read function, and expose only that proxy to the rest
|
||||
of the implementation. If a write function, if needed, handles the conversion
|
||||
from native to the desired output endianness.
|
||||
|
||||
This pattern is appropriate when all endian elements in a record are typically
|
||||
used regardless of record content or other circumstances.
|
||||
|
||||
### Convert only as needed, except locally in anticipation of need
|
||||
|
||||
This pattern in general defers conversion but for specific local needs does
|
||||
anticipatory conversion. Although particularly appropriate when coupled with the
|
||||
endian buffer or arithmetic types, it also works well with the conversion
|
||||
functions.
|
||||
|
||||
Example:
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
struct data_t
|
||||
{
|
||||
big_int32_t v1;
|
||||
big_int32_t v2;
|
||||
big_int32_t v3;
|
||||
};
|
||||
|
||||
data_t data;
|
||||
|
||||
read(data);
|
||||
|
||||
...
|
||||
++v1;
|
||||
...
|
||||
|
||||
int32_t v3_temp = data.v3; // hoist conversion out of loop
|
||||
|
||||
for (int32_t i = 0; i < `large-number`; ++i)
|
||||
{
|
||||
... `lengthy computation that accesses v3_temp` ...
|
||||
}
|
||||
data.v3 = v3_temp;
|
||||
|
||||
write(data);
|
||||
```
|
||||
|
||||
In general the above pseudo-code leaves conversion up to the endian arithmetic
|
||||
type `big_int32_t`. But to avoid conversion inside the loop, a temporary is
|
||||
created before the loop is entered, and then used to set the new value of
|
||||
`data.v3` after the loop is complete.
|
||||
|
||||
Question: Won't the compiler's optimizer hoist the conversion out of the loop
|
||||
anyhow?
|
||||
|
||||
Answer: V{cpp} 2015 Preview, and probably others, does not, even for a toy test
|
||||
program. Although the savings is small (two register `bswap` instructions), the
|
||||
cost might be significant if the loop is repeated enough times. On the other
|
||||
hand, the program may be so dominated by I/O time that even a lengthy loop will
|
||||
be immaterial.
|
||||
|
||||
## Use case examples
|
||||
|
||||
### Porting endian unaware codebase
|
||||
|
||||
An existing codebase runs on big endian systems. It does not currently deal
|
||||
with endianness. The codebase needs to be modified so it can run on little
|
||||
endian systems under various operating systems. To ease transition and protect
|
||||
value of existing files, external data will continue to be maintained as big
|
||||
endian.
|
||||
|
||||
The <<arithmetic,endian arithmetic approach>> is recommended to meet these
|
||||
needs. A relatively small number of header files dealing with binary I/O layouts
|
||||
need to change types. For example, `short` or `int16_t` would change to
|
||||
`big_int16_t`. No changes are required for `.cpp` files.
|
||||
|
||||
### Porting endian aware codebase
|
||||
|
||||
An existing codebase runs on little-endian Linux systems. It already deals with
|
||||
endianness via
|
||||
http://man7.org/linux/man-pages/man3/endian.3.html[Linux provided functions].
|
||||
Because of a business merger, the codebase has to be quickly modified for
|
||||
Windows and possibly other operating systems, while still supporting Linux. The
|
||||
codebase is reliable and the programmers are all well-aware of endian issues.
|
||||
|
||||
These factors all argue for an <<conversion, endian conversion approach>> that
|
||||
just mechanically changes the calls to `htobe32`, etc. to
|
||||
`boost::endian::native_to_big`, etc. and replaces `<endian.h>` with
|
||||
`<boost/endian/conversion.hpp>`.
|
||||
|
||||
### Reliability and arithmetic-speed
|
||||
|
||||
A new, complex, multi-threaded application is to be developed that must run
|
||||
on little endian machines, but do big endian network I/O. The developers believe
|
||||
computational speed for endian variable is critical but have seen numerous bugs
|
||||
result from inability to reason about endian conversion state. They are also
|
||||
worried that future maintenance changes could inadvertently introduce a lot of
|
||||
slow conversions if full-blown endian arithmetic types are used.
|
||||
|
||||
The <<buffers,endian buffers>> approach is made-to-order for this use case.
|
||||
|
||||
### Reliability and ease-of-use
|
||||
|
||||
A new, complex, multi-threaded application is to be developed that must run on
|
||||
little endian machines, but do big endian network I/O. The developers believe
|
||||
computational speed for endian variables is *not critical* but have seen
|
||||
numerous bugs result from inability to reason about endian conversion state.
|
||||
They are also concerned about ease-of-use both during development and long-term
|
||||
maintenance.
|
||||
|
||||
Removing concern about conversion speed and adding concern about ease-of-use
|
||||
tips the balance strongly in favor the
|
||||
<<arithmetic,endian arithmetic approach>>.
|
589
doc/endian/conversion.adoc
Normal file
589
doc/endian/conversion.adoc
Normal file
@ -0,0 +1,589 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#conversion]
|
||||
# Endian Conversion Functions
|
||||
:idprefix: conversion_
|
||||
|
||||
## Introduction
|
||||
|
||||
Header `boost/endian/conversion.hpp` provides byte order reversal and conversion
|
||||
functions that convert objects of the built-in integer types between native,
|
||||
big, or little endian byte ordering. User defined types are also supported.
|
||||
|
||||
## Reference
|
||||
|
||||
Functions are implemented `inline` if appropriate. For {cpp}03 compilers,
|
||||
`noexcept` is elided. Boost scoped enum emulation is used so that the library
|
||||
still works for compilers that do not support scoped enums.
|
||||
|
||||
### Definitions
|
||||
|
||||
*Endianness* refers to the ordering of bytes within internal or external
|
||||
integers and other arithmetic data. Most-significant byte first is called
|
||||
*big endian* ordering. Least-significant byte first is called
|
||||
*little endian* ordering. Other orderings are possible and some CPU
|
||||
architectures support both big and little ordering.
|
||||
|
||||
NOTE: The names are derived from
|
||||
http://en.wikipedia.org/wiki/Jonathan_Swift[Jonathan Swift]'s satirical novel
|
||||
_http://en.wikipedia.org/wiki/Gulliver's_Travels[Gulliver's Travels]_, where
|
||||
rival kingdoms opened their soft-boiled eggs at different ends. Wikipedia has an
|
||||
extensive description of https://en.wikipedia.org/wiki/Endianness[Endianness].
|
||||
|
||||
The standard integral types ({cpp}std [basic.fundamental]) except `bool` and
|
||||
the scoped enumeration types ({cpp}std [dcl.enum]) are collectively called the
|
||||
*endian types*. In the absence of padding bits, which is true on the platforms
|
||||
supported by the Boost.Endian library, endian types have the property that all
|
||||
of their bit patterns are valid values, which means that when an object of an
|
||||
endian type has its constituent bytes reversed, the result is another valid value.
|
||||
This allows `endian_reverse` to take and return by value.
|
||||
|
||||
Other built-in types, such as `bool`, `float`, or unscoped enumerations, do not
|
||||
have the same property, which means that reversing their constituent bytes may
|
||||
produce an invalid value, leading to undefined behavior. These types are therefore
|
||||
disallowed in `endian_reverse`, but are still allowed in `endian_reverse_inplace`.
|
||||
Even if an object becomes invalid as a result of reversing its bytes, as long as
|
||||
its value is never read, there would be no undefined behavior.
|
||||
|
||||
### Header `<boost/endian/conversion.hpp>` Synopsis
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
#define BOOST_ENDIAN_INTRINSIC_MSG \
|
||||
"`message describing presence or absence of intrinsics`"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
enum class order
|
||||
{
|
||||
native = `see below`,
|
||||
big = `see below`,
|
||||
little = `see below`,
|
||||
};
|
||||
|
||||
// Byte reversal functions
|
||||
|
||||
template <class Endian>
|
||||
Endian endian_reverse(Endian x) noexcept;
|
||||
|
||||
template <class EndianReversible>
|
||||
EndianReversible big_to_native(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_big(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible little_to_native(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_little(EndianReversible x) noexcept;
|
||||
|
||||
template <order O1, order O2, class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x) noexcept;
|
||||
template <class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x,
|
||||
order order1, order order2) noexcept;
|
||||
|
||||
// In-place byte reversal functions
|
||||
|
||||
template <class EndianReversible>
|
||||
void endian_reverse_inplace(EndianReversible& x) noexcept;
|
||||
|
||||
template<class EndianReversibleInplace, std::size_t N>
|
||||
void endian_reverse_inplace(EndianReversibleInplace (&x)[N]) noexcept;
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
void big_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_big_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void little_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_little_inplace(EndianReversibleInplace& x) noexcept;
|
||||
|
||||
template <order O1, order O2, class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept;
|
||||
template <class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x,
|
||||
order order1, order order2) noexcept;
|
||||
|
||||
// Generic load and store functions
|
||||
|
||||
template<class T, std::size_t N, order Order>
|
||||
T endian_load( unsigned char const * p ) noexcept;
|
||||
|
||||
template<class T, std::size_t N, order Order>
|
||||
void endian_store( unsigned char * p, T const & v ) noexcept;
|
||||
|
||||
// Convenience load functions
|
||||
|
||||
boost::int16_t load_little_s16( unsigned char const * p ) noexcept;
|
||||
boost::uint16_t load_little_u16( unsigned char const * p ) noexcept;
|
||||
boost::int16_t load_big_s16( unsigned char const * p ) noexcept;
|
||||
boost::uint16_t load_big_u16( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int32_t load_little_s24( unsigned char const * p ) noexcept;
|
||||
boost::uint32_t load_little_u24( unsigned char const * p ) noexcept;
|
||||
boost::int32_t load_big_s24( unsigned char const * p ) noexcept;
|
||||
boost::uint32_t load_big_u24( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int32_t load_little_s32( unsigned char const * p ) noexcept;
|
||||
boost::uint32_t load_little_u32( unsigned char const * p ) noexcept;
|
||||
boost::int32_t load_big_s32( unsigned char const * p ) noexcept;
|
||||
boost::uint32_t load_big_u32( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int64_t load_little_s40( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_little_u40( unsigned char const * p ) noexcept;
|
||||
boost::int64_t load_big_s40( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_big_u40( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int64_t load_little_s48( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_little_u48( unsigned char const * p ) noexcept;
|
||||
boost::int64_t load_big_s48( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_big_u48( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int64_t load_little_s56( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_little_u56( unsigned char const * p ) noexcept;
|
||||
boost::int64_t load_big_s56( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_big_u56( unsigned char const * p ) noexcept;
|
||||
|
||||
boost::int64_t load_little_s64( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_little_u64( unsigned char const * p ) noexcept;
|
||||
boost::int64_t load_big_s64( unsigned char const * p ) noexcept;
|
||||
boost::uint64_t load_big_u64( unsigned char const * p ) noexcept;
|
||||
|
||||
// Convenience store functions
|
||||
|
||||
void store_little_s16( unsigned char * p, boost::int16_t v ) noexcept;
|
||||
void store_little_u16( unsigned char * p, boost::uint16_t v ) noexcept;
|
||||
void store_big_s16( unsigned char * p, boost::int16_t v ) noexcept;
|
||||
void store_big_u16( unsigned char * p, boost::uint16_t v ) noexcept;
|
||||
|
||||
void store_little_s24( unsigned char * p, boost::int32_t v ) noexcept;
|
||||
void store_little_u24( unsigned char * p, boost::uint32_t v ) noexcept;
|
||||
void store_big_s24( unsigned char * p, boost::int32_t v ) noexcept;
|
||||
void store_big_u24( unsigned char * p, boost::uint32_t v ) noexcept;
|
||||
|
||||
void store_little_s32( unsigned char * p, boost::int32_t v ) noexcept;
|
||||
void store_little_u32( unsigned char * p, boost::uint32_t v ) noexcept;
|
||||
void store_big_s32( unsigned char * p, boost::int32_t v ) noexcept;
|
||||
void store_big_u32( unsigned char * p, boost::uint32_t v ) noexcept;
|
||||
|
||||
void store_little_s40( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_little_u40( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
void store_big_s40( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_big_u40( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
|
||||
void store_little_s48( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_little_u48( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
void store_big_s48( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_big_u48( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
|
||||
void store_little_s56( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_little_u56( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
void store_big_s56( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_big_u56( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
|
||||
void store_little_s64( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_little_u64( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
void store_big_s64( unsigned char * p, boost::int64_t v ) noexcept;
|
||||
void store_big_u64( unsigned char * p, boost::uint64_t v ) noexcept;
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
The values of `order::little` and `order::big` shall not be equal to one
|
||||
another.
|
||||
|
||||
The value of `order::native` shall be:
|
||||
|
||||
* equal to `order::big` if the execution environment is big endian, otherwise
|
||||
* equal to `order::little` if the execution environment is little endian,
|
||||
otherwise
|
||||
* unequal to both `order::little` and `order::big`.
|
||||
|
||||
### Requirements
|
||||
|
||||
#### Template argument requirements
|
||||
|
||||
The template definitions in the `boost/endian/conversion.hpp` header refer to
|
||||
various named requirements whose details are set out in the tables in this
|
||||
subsection. In these tables, `T` is an object or reference type to be supplied
|
||||
by a {cpp} program instantiating a template; `x` is a value of type (possibly
|
||||
`const`) `T`; `mlx` is a modifiable lvalue of type `T`.
|
||||
|
||||
[#conversion_endianreversible]
|
||||
##### EndianReversible requirements (in addition to `CopyConstructible`)
|
||||
|
||||
[%header,cols=3*]
|
||||
|===
|
||||
|Expression |Return |Requirements
|
||||
|`endian_reverse(x)` |`T`
|
||||
a|`T` is an endian type or a class type.
|
||||
|
||||
If `T` is an endian type, returns the value of `x` with the order of bytes
|
||||
reversed.
|
||||
|
||||
If `T` is a class type, the function:
|
||||
|
||||
* Is expected to be implemented by the user, as a non-member function in the same
|
||||
namespace as `T` that can be found by argument dependent lookup (ADL);
|
||||
* Should return the value of `x` with the order of bytes reversed for all data members
|
||||
of types or arrays of types that meet the `EndianReversible` requirements.
|
||||
|===
|
||||
|
||||
[#conversion_endianreversibleinplace]
|
||||
##### EndianReversibleInplace requirements
|
||||
|
||||
[%header,cols=2*]
|
||||
|===
|
||||
|Expression |Requirements
|
||||
|`endian_reverse_inplace(mlx)`
|
||||
a|`T` is an integral type, an enumeration type, `float`, `double`, a class type,
|
||||
or an array type.
|
||||
|
||||
If `T` is not a class type or an array type, reverses the order of bytes in `mlx`.
|
||||
|
||||
If `T` is a class type, the function:
|
||||
|
||||
* Is expected to be implemented by the user, as a non-member function in the same
|
||||
namespace as `T` that can be found by argument dependent lookup (ADL);
|
||||
* Should reverse the order of bytes of all data members of `mlx` that have types or
|
||||
arrays of types that meet the `EndianReversible` or `EndianReversibleInplace`
|
||||
requirements.
|
||||
|
||||
If `T` is an array type, calls `endian_reverse_inplace` on each element.
|
||||
|===
|
||||
|
||||
NOTE: Because there is a function template for `endian_reverse_inplace` that
|
||||
calls `endian_reverse` for class types, only `endian_reverse` is required for a
|
||||
user-defined type to meet the `EndianReversibleInplace` requirements. Although
|
||||
user-defined types are not required to supply an `endian_reverse_inplace` function,
|
||||
doing so may improve efficiency.
|
||||
|
||||
#### Customization points for user-defined types (UDTs)
|
||||
|
||||
This subsection describes requirements on the Endian library's implementation.
|
||||
|
||||
The library's function templates requiring
|
||||
`<<conversion_endianreversible,EndianReversible>>` are required to perform
|
||||
reversal of endianness if needed by making an unqualified call to
|
||||
`endian_reverse()`.
|
||||
|
||||
The library's function templates requiring
|
||||
`<<conversion_endianreversibleinplace,EndianReversibleInplace>>` are required to
|
||||
perform reversal of endianness if needed by making an unqualified call to
|
||||
`endian_reverse_inplace()`.
|
||||
|
||||
See `example/udt_conversion_example.cpp` for an example user-defined type.
|
||||
|
||||
### Byte Reversal Functions
|
||||
|
||||
```
|
||||
template <class Endian>
|
||||
Endian endian_reverse(Endian x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `Endian` must be a standard integral type that is not `bool`,
|
||||
or a scoped enumeration type.
|
||||
Returns:: `x`, with the order of its constituent bytes reversed.
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
EndianReversible big_to_native(EndianReversible x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `conditional_reverse<order::big, order::native>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_big(EndianReversible x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `conditional_reverse<order::native, order::big>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
EndianReversible little_to_native(EndianReversible x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `conditional_reverse<order::little, order::native>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
EndianReversible native_to_little(EndianReversible x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `conditional_reverse<order::native, order::little>(x)`.
|
||||
|
||||
```
|
||||
template <order O1, order O2, class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns:: `x` if `O1 == O2,` otherwise `endian_reverse(x)`.
|
||||
Remarks:: Whether `x` or `endian_reverse(x)` is to be returned shall be
|
||||
determined at compile time.
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
EndianReversible conditional_reverse(EndianReversible x,
|
||||
order order1, order order2) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns::
|
||||
`order1 == order2? x: endian_reverse(x)`.
|
||||
|
||||
### In-place Byte Reversal Functions
|
||||
|
||||
```
|
||||
template <class EndianReversible>
|
||||
void endian_reverse_inplace(EndianReversible& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: When `EndianReversible` is a class type,
|
||||
`x = endian_reverse(x);`. When `EndianReversible` is an integral
|
||||
type, an enumeration type, `float`, or `double`, reverses the
|
||||
order of the constituent bytes of `x`. Otherwise, the program is
|
||||
ill-formed.
|
||||
|
||||
```
|
||||
template<class EndianReversibleInplace, std::size_t N>
|
||||
void endian_reverse_inplace(EndianReversibleInplace (&x)[N]) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: Calls `endian_reverse_inplace(x[i])` for `i` from `0` to `N-1`.
|
||||
|
||||
```
|
||||
template <class EndianReversibleInplace>
|
||||
void big_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `conditional_reverse_inplace<order::big, order::native>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_big_inplace(EndianReversibleInplace& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `conditional_reverse_inplace<order::native, order::big>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversibleInplace>
|
||||
void little_to_native_inplace(EndianReversibleInplace& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `conditional_reverse_inplace<order::little, order::native>(x)`.
|
||||
|
||||
```
|
||||
template <class EndianReversibleInplace>
|
||||
void native_to_little_inplace(EndianReversibleInplace& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `conditional_reverse_inplace<order::native, order::little>(x)`.
|
||||
|
||||
```
|
||||
template <order O1, order O2, class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: None if `O1 == O2,` otherwise `endian_reverse_inplace(x)`.
|
||||
Remarks:: Which effect applies shall be determined at compile time.
|
||||
|
||||
```
|
||||
template <class EndianReversibleInplace>
|
||||
void conditional_reverse_inplace(EndianReversibleInplace& x,
|
||||
order order1, order order2) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects::
|
||||
If `order1 == order2` then `endian_reverse_inplace(x)`.
|
||||
|
||||
### Generic Load and Store Functions
|
||||
|
||||
```
|
||||
template<class T, std::size_t N, order Order>
|
||||
T endian_load( unsigned char const * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `sizeof(T)` must be 1, 2, 4, or 8. `N` must be between 1 and
|
||||
`sizeof(T)`, inclusive. `T` must be trivially copyable. If `N` is not
|
||||
equal to `sizeof(T)`, `T` must be integral or `enum`.
|
||||
|
||||
Effects:: Reads `N` bytes starting from `p`, in forward or reverse order
|
||||
depending on whether `Order` matches the native endianness or not,
|
||||
interprets the resulting bit pattern as a value of type `T`, and returns it.
|
||||
If `sizeof(T)` is bigger than `N`, zero-extends when `T` is unsigned,
|
||||
sign-extends otherwise.
|
||||
|
||||
```
|
||||
template<class T, std::size_t N, order Order>
|
||||
void endian_store( unsigned char * p, T const & v ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `sizeof(T)` must be 1, 2, 4, or 8. `N` must be between 1 and
|
||||
`sizeof(T)`, inclusive. `T` must be trivially copyable. If `N` is not
|
||||
equal to `sizeof(T)`, `T` must be integral or `enum`.
|
||||
|
||||
Effects:: Writes to `p` the `N` least significant bytes from the object
|
||||
representation of `v`, in forward or reverse order depending on whether
|
||||
`Order` matches the native endianness or not.
|
||||
|
||||
### Convenience Load Functions
|
||||
|
||||
```
|
||||
inline boost::intM_t load_little_sN( unsigned char const * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Reads an N-bit signed little-endian integer from `p`.
|
||||
+
|
||||
Returns:: `endian_load<boost::intM_t, N/8, order::little>( p )`.
|
||||
|
||||
```
|
||||
inline boost::uintM_t load_little_uN( unsigned char const * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Reads an N-bit unsigned little-endian integer from `p`.
|
||||
+
|
||||
Returns:: `endian_load<boost::uintM_t, N/8, order::little>( p )`.
|
||||
|
||||
```
|
||||
inline boost::intM_t load_big_sN( unsigned char const * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Reads an N-bit signed big-endian integer from `p`.
|
||||
+
|
||||
Returns:: `endian_load<boost::intM_t, N/8, order::big>( p )`.
|
||||
|
||||
```
|
||||
inline boost::uintM_t load_big_uN( unsigned char const * p ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Reads an N-bit unsigned big-endian integer from `p`.
|
||||
+
|
||||
Returns::
|
||||
`endian_load<boost::uintM_t, N/8, order::big>( p )`.
|
||||
|
||||
### Convenience Store Functions
|
||||
|
||||
```
|
||||
inline void store_little_sN( unsigned char * p, boost::intM_t v ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Writes an N-bit signed little-endian integer to `p`.
|
||||
+
|
||||
Effects:: `endian_store<boost::intM_t, N/8, order::little>( p, v )`.
|
||||
|
||||
```
|
||||
inline void store_little_uN( unsigned char * p, boost::uintM_t v ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Writes an N-bit unsigned little-endian integer to `p`.
|
||||
+
|
||||
Effects:: `endian_store<boost::uintM_t, N/8, order::little>( p, v )`.
|
||||
|
||||
```
|
||||
inline void store_big_sN( unsigned char * p, boost::intM_t v ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Writes an N-bit signed big-endian integer to `p`.
|
||||
+
|
||||
Effects:: `endian_store<boost::intM_t, N/8, order::big>( p, v )`.
|
||||
|
||||
```
|
||||
inline void store_big_uN( unsigned char * p, boost::uintM_t v ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Writes an N-bit unsigned big-endian integer to `p`.
|
||||
+
|
||||
Effects::
|
||||
`endian_store<boost::uintM_t, N/8, order::big>( p, v )`.
|
||||
|
||||
## FAQ
|
||||
|
||||
See the <<overview_faq,Overview FAQ>> for a library-wide FAQ.
|
||||
|
||||
Why are both value returning and modify-in-place functions provided?::
|
||||
Returning the result by value is the standard C and {cpp} idiom for functions
|
||||
that compute a value from an argument. Modify-in-place functions allow cleaner
|
||||
code in many real-world endian use cases and are more efficient for user-defined
|
||||
types that have members such as string data that do not need to be reversed.
|
||||
Thus both forms are provided.
|
||||
|
||||
Why not use the Linux names (htobe16, htole16, be16toh, le16toh, etc.) ?::
|
||||
Those names are non-standard and vary even between POSIX-like operating
|
||||
systems. A {cpp} library TS was going to use those names, but found they were
|
||||
sometimes implemented as macros. Since macros do not respect scoping and
|
||||
namespace rules, to use them would be very error prone.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Tomas Puverle was instrumental in identifying and articulating the need to
|
||||
support endian conversion as separate from endian integer types. Phil Endecott
|
||||
suggested the form of the value returning signatures. Vicente Botet and other
|
||||
reviewers suggested supporting user defined types. General reverse template
|
||||
implementation approach using `std::reverse` suggested by Mathias Gaunard.
|
||||
Portable implementation approach for 16, 32, and 64-bit integers suggested by
|
||||
tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero
|
||||
Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins
|
||||
implementation approach for 16, 32, and 64-bit integers suggested by several
|
||||
reviewers, and by David Stone, who provided his Boost licensed macro
|
||||
implementation that became the starting point for
|
||||
`boost/endian/detail/intrinsic.hpp`. Pierre Talbot provided the
|
||||
`int8_t endian_reverse()` and templated `endian_reverse_inplace()`
|
||||
implementations.
|
167
doc/endian/history.adoc
Normal file
167
doc/endian/history.adoc
Normal file
@ -0,0 +1,167 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#appendix_history]
|
||||
[appendix]
|
||||
# History and Acknowledgments
|
||||
:idprefix: apph_
|
||||
|
||||
## History
|
||||
|
||||
### Changes requested by formal review
|
||||
|
||||
The library was reworked from top to bottom to accommodate changes requested
|
||||
during the formal review. The issues that were required to be resolved before
|
||||
a mini-review are shown in *bold* below, with the resolution indicated.
|
||||
|
||||
Common use case scenarios should be developed.::
|
||||
Done. The documentation have been refactored. A page is now devoted to
|
||||
<<choosing,Choosing the Approach>> to endianness. See
|
||||
<<choosing_use_cases,Use cases>> for use case scenarios.
|
||||
|
||||
Example programs should be developed for the common use case scenarios.::
|
||||
Done. See <<choosing,Choosing the Approach>>. Example code has been added
|
||||
throughout.
|
||||
|
||||
Documentation should illuminate the differences between endian integer/float type and endian conversion approaches to the common use case scenarios, and provide guidelines for choosing the most appropriate approach in user's applications.::
|
||||
Done. See <<choosing,Choosing the Approach>>.
|
||||
|
||||
Conversion functions supplying results via return should be provided.::
|
||||
Done. See <<conversion,Conversion Functions>>.
|
||||
|
||||
Platform specific performance enhancements such as use of compiler intrinsics or relaxed alignment requirements should be supported.::
|
||||
Done. Compiler (Clang, GCC, Visual{cpp}, etc.) intrinsics and built-in
|
||||
functions are used in the implementation where appropriate, as requested. See
|
||||
<<overview_intrinsic,Built-in support for Intrinsics>>. See
|
||||
<<overview_timings,Timings for Example 2>> to gauge the impact of intrinsics.
|
||||
|
||||
Endian integer (and floating) types should be implemented via the conversion functions. If that can't be done efficiently, consideration should be given to expanding the conversion function signatures to resolve the inefficiencies.::
|
||||
Done. For the endian types, the implementation uses the endian conversion
|
||||
functions, and thus the intrinsics, as requested.
|
||||
|
||||
Benchmarks that measure performance should be provided. It should be possible to compare platform specific performance enhancements against portable base implementations, and to compare endian integer approaches against endian conversion approaches for the common use case scenarios.::
|
||||
Done. See <<overview_timings,Timings for Example 2>>. The `endian/test`
|
||||
directory also contains several additional benchmark and speed test programs.
|
||||
|
||||
Float (32-bits) and double (64-bits) should be supported. IEEE 754 is the primary use case.::
|
||||
Done. The <<buffers,endian buffer types>>,
|
||||
<<arithmetic,endian arithmetic types>> and
|
||||
<<conversion,endian conversion functions>> now support 32-bit `(float)`
|
||||
and 64-bit `(double)` floating point, as requested.
|
||||
|
||||
NOTE: This answer is outdated. The support for `float` and `double` was subsequently found
|
||||
problematic and has been removed. Recently, support for `float` and `double` has
|
||||
been reinstated for `endian_buffer` and `endian_arithmetic`, but not for the
|
||||
conversion functions.
|
||||
|
||||
Support for user defined types (UDTs) is desirable, and should be provided where there would be no conflict with the other concerns.::
|
||||
Done. See <<conversion_customization,Customization points for user-defined
|
||||
types (UDTs)>>.
|
||||
|
||||
There is some concern that endian integer/float arithmetic operations might used inadvertently or inappropriately. The impact of adding an endian_buffer class without arithmetic operations should be investigated.::
|
||||
Done. The endian types have been decomposed into class template
|
||||
`<<buffers,endian_buffer>>` and class template
|
||||
`<<arithmetic,endian_arithmetic>>`. Class `endian_buffer` is a public base
|
||||
class for `endian_arithmetic`, and can also be used by users as a stand-alone
|
||||
class.
|
||||
|
||||
Stream insertion and extraction of the endian integer/float types should be documented and included in the test coverage.::
|
||||
Done. See <<buffers_stream_inserter,Stream inserter>> and
|
||||
<<buffers_stream_extractor,Stream extractor>>.
|
||||
|
||||
Binary I/O support that was investigated during development of the Endian library should be put up for mini-review for inclusion in the Boost I/O library.::
|
||||
Not done yet. Will be handled as a separate min-review soon after the Endian
|
||||
mini-review.
|
||||
|
||||
Other requested changes.::
|
||||
* In addition to the named-endianness conversion functions, functions that
|
||||
perform compile-time (via template) and run-time (via function argument)
|
||||
dispatch are now provided.
|
||||
* `order::native` is now a synonym for `order::big` or `order::little` according
|
||||
to the endianness of the platform. This reduces the number of template
|
||||
specializations required.
|
||||
* Headers have been reorganized to make them easier to read, with a synopsis
|
||||
at the front and implementation following.
|
||||
|
||||
### Other changes since formal review
|
||||
|
||||
* Header `boost/endian/endian.hpp` has been renamed to
|
||||
`boost/endian/arithmetic.hpp`. Headers
|
||||
`boost/endian/conversion.hpp` and `boost/endian/buffers.hpp` have been added.
|
||||
Infrastructure file names were changed accordingly.
|
||||
* The endian arithmetic type aliases have been renamed, using a naming pattern
|
||||
that is consistent for both integer and floating point, and a consistent set of
|
||||
aliases supplied for the endian buffer types.
|
||||
* The unaligned-type alias names still have the `_t` suffix, but the
|
||||
aligned-type alias names now have an `_at` suffix.
|
||||
* `endian_reverse()` overloads for `int8_t` and `uint8_t` have been added for
|
||||
improved generality. (Pierre Talbot)
|
||||
* Overloads of `endian_reverse_inplace()` have been replaced with a single
|
||||
`endian_reverse_inplace()` template. (Pierre Talbot)
|
||||
* For X86 and X64 architectures, which permit unaligned loads and stores,
|
||||
unaligned little endian buffer and arithmetic types use regular loads and
|
||||
stores when the size is exact. This makes unaligned little endian buffer and
|
||||
arithmetic types significantly more efficient on these architectures. (Jeremy
|
||||
Maitin-Shepard)
|
||||
* {cpp}11 features affecting interfaces, such as `noexcept`, are now used.
|
||||
{cpp}03 compilers are still supported.
|
||||
* Acknowledgements have been updated.
|
||||
|
||||
## Compatibility with interim releases
|
||||
|
||||
Prior to the official Boost release, class template `endian_arithmetic` has been
|
||||
used for a decade or more with the same functionality but under the name
|
||||
`endian`. Other names also changed in the official release. If the macro
|
||||
`BOOST_ENDIAN_DEPRECATED_NAMES` is defined, those old now deprecated names are
|
||||
still supported. However, the class template `endian` name is only provided for
|
||||
compilers supporting {cpp}11 template aliases. For {cpp}03 compilers, the name
|
||||
will have to be changed to `endian_arithmetic`.
|
||||
|
||||
To support backward header compatibility, deprecated header
|
||||
`boost/endian/endian.hpp` forwards to `boost/endian/arithmetic.hpp`. It requires
|
||||
`BOOST_ENDIAN_DEPRECATED_NAMES` be defined. It should only be used while
|
||||
transitioning to the official Boost release of the library as it will be removed
|
||||
in some future release.
|
||||
|
||||
## Future directions
|
||||
|
||||
Standardization.::
|
||||
The plan is to submit Boost.Endian to the {cpp} standards committee for possible
|
||||
inclusion in a Technical Specification or the {cpp} standard itself.
|
||||
|
||||
Specializations for `numeric_limits`.::
|
||||
Roger Leigh requested that all `boost::endian` types provide `numeric_limits`
|
||||
specializations.
|
||||
See https://github.com/boostorg/endian/issues/4[GitHub issue 4].
|
||||
|
||||
Character buffer support.::
|
||||
Peter Dimov pointed out during the mini-review that getting and setting basic
|
||||
arithmetic types (or `<cstdint>` equivalents) from/to an offset into an array of
|
||||
unsigned char is a common need. See
|
||||
http://lists.boost.org/Archives/boost/2015/01/219574.php[Boost.Endian
|
||||
mini-review posting].
|
||||
|
||||
Out-of-range detection.::
|
||||
Peter Dimov pointed suggested during the mini-review that throwing an exception
|
||||
on buffer values being out-of-range might be desirable. See the end of
|
||||
http://lists.boost.org/Archives/boost/2015/01/219659.php[this posting] and
|
||||
subsequent replies.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Comments and suggestions were received from Adder, Benaka Moorthi, Christopher
|
||||
Kohlhoff, Cliff Green, Daniel James, Dave Handley, Gennaro Proto, Giovanni Piero
|
||||
Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Howard Hinnant, Jason Newton,
|
||||
Jeff Flinn, Jeremy Maitin-Shepard, John Filo, John Maddock, Kim Barrett, Marsh
|
||||
Ray, Martin Bonner, Mathias Gaunard, Matias Capeletto, Neil Mayhew, Nevin Liber,
|
||||
Olaf van der Spek, Paul Bristow, Peter Dimov, Pierre Talbot, Phil Endecott,
|
||||
Philip Bennefall, Pyry Jahkola, Rene Rivera, Robert Stewart, Roger Leigh, Roland
|
||||
Schwarz, Scott McMurray, Sebastian Redl, Tim Blechmann, Tim Moore, tymofey,
|
||||
Tomas Puverle, Vincente Botet, Yuval Ronen and Vitaly Budovsk. Apologies if
|
||||
anyone has been missed.
|
||||
|
||||
The documentation was converted into Asciidoc format by Glen Fernandes.
|
366
doc/endian/overview.adoc
Normal file
366
doc/endian/overview.adoc
Normal file
@ -0,0 +1,366 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#overview]
|
||||
# Overview
|
||||
:idprefix: overview_
|
||||
|
||||
## Abstract
|
||||
|
||||
Boost.Endian provides facilities to manipulate the
|
||||
<<overview_endianness,endianness>> of integers and user-defined types.
|
||||
|
||||
* Three approaches to endianness are supported. Each has a long history of
|
||||
successful use, and each approach has use cases where it is preferred over the
|
||||
other approaches.
|
||||
* Primary uses:
|
||||
** Data portability. The Endian library supports binary data exchange, via
|
||||
either external media or network transmission, regardless of platform
|
||||
endianness.
|
||||
** Program portability. POSIX-based and Windows-based operating systems
|
||||
traditionally supply libraries with non-portable functions to perform endian
|
||||
conversion. There are at least four incompatible sets of functions in common
|
||||
use. The Endian library is portable across all {cpp} platforms.
|
||||
* Secondary use: Minimizing data size via sizes and/or alignments not supported
|
||||
by the standard {cpp} integer types.
|
||||
|
||||
[#overview_endianness]
|
||||
## Introduction to endianness
|
||||
|
||||
Consider the following code:
|
||||
|
||||
```
|
||||
int16_t i = 0x0102;
|
||||
FILE * file = fopen("test.bin", "wb"); // binary file!
|
||||
fwrite(&i, sizeof(int16_t), 1, file);
|
||||
fclose(file);
|
||||
```
|
||||
|
||||
On OS X, Linux, or Windows systems with an Intel CPU, a hex dump of the
|
||||
"test.bin" output file produces:
|
||||
|
||||
```
|
||||
0201
|
||||
```
|
||||
|
||||
On OS X systems with a PowerPC CPU, or Solaris systems with a SPARC CPU, a hex
|
||||
dump of the "test.bin" output file produces:
|
||||
|
||||
```
|
||||
0102
|
||||
```
|
||||
|
||||
What's happening here is that Intel CPUs order the bytes of an integer with the
|
||||
least-significant byte first, while SPARC CPUs place the most-significant byte
|
||||
first. Some CPUs, such as the PowerPC, allow the operating system to choose
|
||||
which ordering applies.
|
||||
|
||||
Most-significant-byte-first ordering is traditionally called "big endian"
|
||||
ordering and least-significant-byte-first is traditionally called
|
||||
"little-endian" ordering. The names are derived from
|
||||
http://en.wikipedia.org/wiki/Jonathan_Swift[Jonathan Swift]'s satirical novel
|
||||
_http://en.wikipedia.org/wiki/Gulliver's_Travels[Gulliver's Travels]_, where
|
||||
rival kingdoms opened their soft-boiled eggs at different ends.
|
||||
|
||||
See Wikipedia's http://en.wikipedia.org/wiki/Endianness[Endianness] article for
|
||||
an extensive discussion of endianness.
|
||||
|
||||
Programmers can usually ignore endianness, except when reading a core dump on
|
||||
little-endian systems. But programmers have to deal with endianness when
|
||||
exchanging binary integers and binary floating point values between computer
|
||||
systems with differing endianness, whether by physical file transfer or over a
|
||||
network. And programmers may also want to use the library when minimizing either
|
||||
internal or external data sizes is advantageous.
|
||||
|
||||
[#overview_introduction]
|
||||
## Introduction to the Boost.Endian library
|
||||
|
||||
Boost.Endian provides three different approaches to dealing with endianness. All
|
||||
three approaches support integers and user-define types (UDTs).
|
||||
|
||||
Each approach has a long history of successful use, and each approach has use
|
||||
cases where it is preferred to the other approaches. See
|
||||
<<choosing,Choosing between Conversion Functions, Buffer Types, and Arithmetic Types>>.
|
||||
|
||||
<<conversion,Endian conversion functions>>::
|
||||
The application uses the built-in integer types to hold values, and calls the
|
||||
provided conversion functions to convert byte ordering as needed. Both mutating
|
||||
and non-mutating conversions are supplied, and each comes in unconditional and
|
||||
conditional variants.
|
||||
|
||||
<<buffers, Endian buffer types>>::
|
||||
The application uses the provided endian buffer types to hold values, and
|
||||
explicitly converts to and from the built-in integer types. Buffer sizes of 8,
|
||||
16, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5, 6, 7, and 8 bytes) are
|
||||
provided. Unaligned integer buffer types are provided for all sizes, and aligned
|
||||
buffer types are provided for 16, 32, and 64-bit sizes. The provided specific
|
||||
types are typedefs for a generic class template that may be used directly for
|
||||
less common use cases.
|
||||
|
||||
<<arithmetic, Endian arithmetic types>>::
|
||||
The application uses the provided endian arithmetic types, which supply the same
|
||||
operations as the built-in {cpp} arithmetic types. All conversions are implicit.
|
||||
Arithmetic sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5,
|
||||
6, 7, and 8 bytes) are provided. Unaligned integer types are provided for all
|
||||
sizes and aligned arithmetic types are provided for 16, 32, and 64-bit sizes.
|
||||
The provided specific types are typedefs for a generic class template that may
|
||||
be used directly in generic code of for less common use cases.
|
||||
|
||||
Boost Endian is a header-only library. {cpp}11 features affecting interfaces,
|
||||
such as `noexcept`, are used only if available. See
|
||||
<<overview_cpp03_support,{cpp}03 support for {cpp}11 features>> for details.
|
||||
|
||||
[#overview_intrinsics]
|
||||
## Built-in support for Intrinsics
|
||||
|
||||
Most compilers, including GCC, Clang, and Visual {cpp}, supply built-in support
|
||||
for byte swapping intrinsics. The Endian library uses these intrinsics when
|
||||
available since they may result in smaller and faster generated code,
|
||||
particularly for optimized builds.
|
||||
|
||||
Defining the macro `BOOST_ENDIAN_NO_INTRINSICS` will suppress use of the
|
||||
intrinsics. This is useful when a compiler has no intrinsic support or fails to
|
||||
locate the appropriate header, perhaps because it is an older release or has
|
||||
very limited supporting libraries.
|
||||
|
||||
The macro `BOOST_ENDIAN_INTRINSIC_MSG` is defined as either
|
||||
`"no byte swap intrinsics"` or a string describing the particular set of
|
||||
intrinsics being used. This is useful for eliminating missing intrinsics as a
|
||||
source of performance issues.
|
||||
|
||||
## Performance
|
||||
|
||||
Consider this problem:
|
||||
|
||||
### Example 1
|
||||
Add 100 to a big endian value in a file, then write the result to a file
|
||||
[%header,cols=2*]
|
||||
|===
|
||||
|Endian arithmetic type approach |Endian conversion function approach
|
||||
a|
|
||||
----
|
||||
big_int32_at x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
|
||||
x += 100;
|
||||
|
||||
|
||||
... write x to a file ...
|
||||
----
|
||||
a|
|
||||
----
|
||||
int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
big_to_native_inplace(x);
|
||||
x += 100;
|
||||
native_to_big_inplace(x);
|
||||
|
||||
... write x to a file ...
|
||||
----
|
||||
|===
|
||||
|
||||
*There will be no performance difference between the two approaches in optimized
|
||||
builds, regardless of the native endianness of the machine.* That's because
|
||||
optimizing compilers will generate exactly the same code for each. That
|
||||
conclusion was confirmed by studying the generated assembly code for GCC and
|
||||
Visual {cpp}. Furthermore, time spent doing I/O will determine the speed of this
|
||||
application.
|
||||
|
||||
Now consider a slightly different problem:
|
||||
|
||||
### Example 2
|
||||
Add a million values to a big endian value in a file, then write the result to a
|
||||
file
|
||||
[%header,cols=2*]
|
||||
|===
|
||||
|Endian arithmetic type approach |Endian conversion function approach
|
||||
a|
|
||||
----
|
||||
big_int32_at x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
|
||||
|
||||
for (int32_t i = 0; i < 1000000; ++i)
|
||||
x += i;
|
||||
|
||||
|
||||
|
||||
... write x to a file ...
|
||||
----
|
||||
a|
|
||||
----
|
||||
int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
big_to_native_inplace(x);
|
||||
|
||||
for (int32_t i = 0; i < 1000000; ++i)
|
||||
x += i;
|
||||
|
||||
native_to_big_inplace(x);
|
||||
|
||||
... write x to a file ...
|
||||
----
|
||||
|===
|
||||
|
||||
With the Endian arithmetic approach, on little endian platforms an implicit
|
||||
conversion from and then back to big endian is done inside the loop. With the
|
||||
Endian conversion function approach, the user has ensured the conversions are
|
||||
done outside the loop, so the code may run more quickly on little endian
|
||||
platforms.
|
||||
|
||||
### Timings
|
||||
|
||||
These tests were run against release builds on a circa 2012 4-core little endian
|
||||
X64 Intel Core i5-3570K CPU @ 3.40GHz under Windows 7.
|
||||
|
||||
CAUTION: The Windows CPU timer has very high granularity. Repeated runs of the
|
||||
same tests often yield considerably different results.
|
||||
|
||||
See `test/loop_time_test.cpp` for the actual code and `benchmark/Jamfile.v2` for
|
||||
the build setup.
|
||||
|
||||
#### GNU C++ version 4.8.2 on Linux virtual machine
|
||||
Iterations: 10'000'000'000, Intrinsics: `__builtin_bswap16`, etc.
|
||||
[%header,cols=3*]
|
||||
|===
|
||||
|Test Case |Endian arithmetic type |Endian conversion function
|
||||
|16-bit aligned big endian |8.46 s |5.28 s
|
||||
|16-bit aligned little endian |5.28 s |5.22 s
|
||||
|32-bit aligned big endian |8.40 s |2.11 s
|
||||
|32-bit aligned little endian |2.11 s |2.10 s
|
||||
|64-bit aligned big endian |14.02 s |3.10 s
|
||||
|64-bit aligned little endian |3.00 s |3.03 s
|
||||
|===
|
||||
|
||||
#### Microsoft Visual C++ version 14.0
|
||||
Iterations: 10'000'000'000, Intrinsics: `<cstdlib>` `_byteswap_ushort`, etc.
|
||||
[%header,cols=3*]
|
||||
|===
|
||||
|Test Case |Endian arithmetic type |Endian conversion function
|
||||
|16-bit aligned big endian |8.27 s |5.26 s
|
||||
|16-bit aligned little endian |5.29 s |5.32 s
|
||||
|32-bit aligned big endian |8.36 s |5.24 s
|
||||
|32-bit aligned little endian |5.24 s |5.24 s
|
||||
|64-bit aligned big endian |13.65 s |3.34 s
|
||||
|64-bit aligned little endian |3.35 s |2.73 s
|
||||
|===
|
||||
|
||||
[#overview_cpp03_support]
|
||||
## {cpp}03 support for {cpp}11 features
|
||||
|
||||
[%header,cols=2*]
|
||||
|===
|
||||
|{cpp}11 Feature
|
||||
|Action with {cpp}03 Compilers
|
||||
|Scoped enums
|
||||
|Uses header
|
||||
http://www.boost.org/libs/core/doc/html/core/scoped_enum.html[boost/core/scoped_enum.hpp]
|
||||
to emulate {cpp}11 scoped enums.
|
||||
|`noexcept`
|
||||
|Uses `BOOST_NOEXCEPT` macro, which is defined as null for compilers not
|
||||
supporting this {cpp}11 feature.
|
||||
|{cpp}11 PODs
|
||||
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm[N2342])
|
||||
|Takes advantage of {cpp}03 compilers that relax {cpp}03 POD rules, but see
|
||||
Limitations <<buffers_limitations,here>> and <<arithmetic_limitations,here>>.
|
||||
Also see macros for explicit POD control <<buffers_compilation,here>> and
|
||||
<<arithmetic_compilation,here>>
|
||||
|===
|
||||
|
||||
[#overview_faq]
|
||||
## Overall FAQ
|
||||
|
||||
Is the implementation header only?::
|
||||
Yes.
|
||||
|
||||
Are {cpp}03 compilers supported?::
|
||||
Yes.
|
||||
|
||||
Does the implementation use compiler intrinsic built-in byte swapping?::
|
||||
Yes, if available. See <<overview_intrinsics,Intrinsic built-in support>>.
|
||||
|
||||
Why bother with endianness?::
|
||||
Binary data portability is the primary use case.
|
||||
|
||||
Does endianness have any uses outside of portable binary file or network I/O formats?::
|
||||
Using the unaligned integer types with a size tailored to the application's
|
||||
needs is a minor secondary use that saves internal or external memory space. For
|
||||
example, using `big_int40_buf_t` or `big_int40_t` in a large array saves a lot
|
||||
of space compared to one of the 64-bit types.
|
||||
|
||||
Why bother with binary I/O? Why not just use {cpp} Standard Library stream inserters and extractors?::
|
||||
* Data interchange formats often specify binary integer data. Binary integer
|
||||
data is smaller and therefore I/O is faster and file sizes are smaller. Transfer
|
||||
between systems is less expensive.
|
||||
* Furthermore, binary integer data is of fixed size, and so fixed-size disk
|
||||
records are possible without padding, easing sorting and allowing random access.
|
||||
* Disadvantages, such as the inability to use text utilities on the resulting
|
||||
files, limit usefulness to applications where the binary I/O advantages are
|
||||
paramount.
|
||||
|
||||
Which is better, big-endian or little-endian?::
|
||||
Big-endian tends to be preferred in a networking environment and is a bit more
|
||||
of an industry standard, but little-endian may be preferred for applications
|
||||
that run primarily on x86, x86-64, and other little-endian CPU's. The
|
||||
http://en.wikipedia.org/wiki/Endian[Wikipedia] article gives more pros and cons.
|
||||
|
||||
Why are only big and little native endianness supported?::
|
||||
These are the only endian schemes that have any practical value today. PDP-11
|
||||
and the other middle endian approaches are interesting curiosities but have no
|
||||
relevance for today's {cpp} developers. The same is true for architectures that
|
||||
allow runtime endianness switching. The
|
||||
<<conversion_native_order_specification,specification for native ordering>> has
|
||||
been carefully crafted to allow support for such orderings in the future, should
|
||||
the need arise. Thanks to Howard Hinnant for suggesting this.
|
||||
|
||||
Why do both the buffer and arithmetic types exist?::
|
||||
Conversions in the buffer types are explicit. Conversions in the arithmetic
|
||||
types are implicit. This fundamental difference is a deliberate design feature
|
||||
that would be lost if the inheritance hierarchy were collapsed.
|
||||
The original design provided only arithmetic types. Buffer types were requested
|
||||
during formal review by those wishing total control over when conversion occurs.
|
||||
They also felt that buffer types would be less likely to be misused by
|
||||
maintenance programmers not familiar with the implications of performing a lot
|
||||
of integer operations on the endian arithmetic integer types.
|
||||
|
||||
What is gained by using the buffer types rather than always just using the arithmetic types?::
|
||||
Assurance that hidden conversions are not performed. This is of overriding
|
||||
importance to users concerned about achieving the ultimate in terms of speed.
|
||||
"Always just using the arithmetic types" is fine for other users. When the
|
||||
ultimate in speed needs to be ensured, the arithmetic types can be used in the
|
||||
same design patterns or idioms that would be used for buffer types, resulting in
|
||||
the same code being generated for either types.
|
||||
|
||||
What are the limitations of integer support?::
|
||||
Tests have only been performed on machines that use two's complement
|
||||
arithmetic. The Endian conversion functions only support 8, 16, 32, and 64-bit
|
||||
aligned integers. The endian types only support 8, 16, 24, 32, 40, 48, 56, and
|
||||
64-bit unaligned integers, and 8, 16, 32, and 64-bit aligned integers.
|
||||
|
||||
Is there floating point support?::
|
||||
An attempt was made to support four-byte ``float``s and eight-byte
|
||||
``double``s, limited to
|
||||
http://en.wikipedia.org/wiki/IEEE_floating_point[IEEE 754] (also known as
|
||||
ISO/IEC/IEEE 60559) floating point and further limited to systems where floating
|
||||
point endianness does not differ from integer endianness. Even with those
|
||||
limitations, support for floating point types was not reliable and was removed.
|
||||
For example, simply reversing the endianness of a floating point number can
|
||||
result in a signaling-NAN.
|
||||
+
|
||||
Support for `float` and `double` has since been reinstated for `endian_buffer`,
|
||||
`endian_arithmetic` and the conversion functions that reverse endianness in place.
|
||||
The conversion functions that take and return by value still do not support floating
|
||||
point due to the above issues; reversing the bytes of a floating point number
|
||||
does not necessarily produce another valid floating point number.
|
743
doc/index.html
743
doc/index.html
@ -1,743 +0,0 @@
|
||||
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
<title>Endian Library</title>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||
<tr>
|
||||
<td width="339">
|
||||
<a href="../../../index.html">
|
||||
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86"></a></td>
|
||||
<td align="middle" width="1253">
|
||||
<b>
|
||||
<font size="6">Endian Library</font></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
|
||||
<tr>
|
||||
<td><b><a href="../../../index.htm">Boost Home</a>
|
||||
<a href="index.html">Endian Home</a>
|
||||
<a href="conversion.html">Conversion Functions</a>
|
||||
<a href="arithmetic.html">Arithmetic Types</a>
|
||||
<a href="buffers.html">Buffer Types</a></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p></p>
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<i><b>Contents</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="#Abstract">Abstract</a><br>
|
||||
<a href="#Introduction-to-endianness">Introduction to endianness</a><br>
|
||||
<a href="#Introduction">Introduction to the Boost.Endian library</a><br>
|
||||
<a href="#Choosing">Choosing approaches</a><br>
|
||||
<a href="#Intrinsic">Built-in support for Intrinsics</a><br>
|
||||
<a href="#Performance">Performance</a><br>
|
||||
<a href="#Timings">Timings</a><br>
|
||||
<a href="#Conclusions">Conclusions</a><br>
|
||||
<a href="#FAQ">FAQ</a><br>
|
||||
<a href="#Release-history">Release history</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||
<b><i>Headers</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="../include/boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
||||
<a href="../include/boost/endian/buffers.hpp"><boost/endian/buffers.hpp></a><br>
|
||||
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="Abstract">Abstract</a></h2>
|
||||
|
||||
<p>Boost.Endian provides facilities to manipulate the
|
||||
<a href="#Introduction-to-endianness">endianness</a> of integers,
|
||||
floating point numbers, and user-defined types.</p>
|
||||
<ul>
|
||||
<li>The primary use case is binary I/O for portable data exchange with
|
||||
other systems, via either external media or network transmission.<br>
|
||||
</li>
|
||||
<li>An additional use case is minimizing storage size via sizes and/or
|
||||
alignments not supported by the built-in types.<br>
|
||||
</li>
|
||||
<li>Three approaches to dealing with endianness are provided. Each approach has a
|
||||
long history of successful use, and each approach has use cases where it is
|
||||
preferred over the other approaches.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="Introduction-to-endianness">Introduction to endianness</a></h2>
|
||||
|
||||
<p>Consider the following code:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>int16_t i = 0x0102;
|
||||
FILE * file = fopen("test.bin", "wb"); // binary file!
|
||||
fwrite(&i, sizeof(int16_t), 1, file);
|
||||
fclose(file);</pre>
|
||||
</blockquote>
|
||||
<p>On OS X, Linux, or Windows systems with an Intel CPU, a hex dump
|
||||
of the "test.bin" output file produces:</p>
|
||||
<blockquote>
|
||||
<p><code>0201</code></p>
|
||||
</blockquote>
|
||||
<p>On OS X systems with a PowerPC CPU, or Solaris systems with a SPARC CPU, a hex dump of the "test.bin"
|
||||
output file produces:</p>
|
||||
<blockquote>
|
||||
<p><code>0102</code></p>
|
||||
</blockquote>
|
||||
<p>What's happening here is that Intel CPUs order the bytes of an integer with
|
||||
the least-significant byte first, while SPARC CPUs place the most-significant
|
||||
byte first. Some CPUs, such as the PowerPC, allow the operating system to
|
||||
choose which ordering applies.</p>
|
||||
<p><a name="definition"></a>Most-significant-byte-first ordering is traditionally called "big endian"
|
||||
ordering and the least-significant-byte-first is traditionally called
|
||||
"little-endian" ordering. The names are derived from
|
||||
<a href="http://en.wikipedia.org/wiki/Jonathan_Swift" title="Jonathan Swift">
|
||||
Jonathan Swift</a>'s satirical novel <i>
|
||||
<a href="http://en.wikipedia.org/wiki/Gulliver's_Travels" title="Gulliver's Travels">
|
||||
Gulliver’s Travels</a></i>, where rival kingdoms opened their soft-boiled eggs
|
||||
at different ends.</p>
|
||||
<p>See the Wikipedia's
|
||||
<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> article for an
|
||||
extensive discussion of endianness.</p>
|
||||
<p>Programmers can usually ignore endianness, except when reading a core
|
||||
dump on little-endian systems. But programmers will have to deal with endianness when exchanging binary integers and binary floating point
|
||||
values between computer systems with differing endianness, whether by physical file transfer or over a network.
|
||||
And programmers may also want to use the library when minimizing either internal or
|
||||
external data sizes is advantageous.</p>
|
||||
<h2><a name="Introduction">Introduction</a> to the Boost.Endian library</h2>
|
||||
|
||||
<p>The Boost.Endian library provides three different approaches to dealing with
|
||||
|
||||
endianness. All three approaches support integers, floating point types
|
||||
except <code>long double</code>, and user defined types (UDTs).</p>
|
||||
|
||||
<p>Each approach has a long history of successful use, and each approach has use
|
||||
cases where it is preferred to the other approaches.</p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b><a href="conversion.html">Endian conversion functions</a> -</b> The
|
||||
application uses the built-in integer and floating point types to hold values, and calls the
|
||||
provided conversion functions to convert byte ordering as needed. Both mutating
|
||||
and non-mutating conversions are supplied, and each comes in unconditional and
|
||||
conditional variants.</p>
|
||||
|
||||
<p><b><a href="buffers.html">Endian buffer types</a> -</b> The application uses the provided endian
|
||||
buffer types
|
||||
to hold values, and explicitly converts to and from the built-in integer and
|
||||
floating point types to perform arithmetic. Buffer lengths of 1 through 8 bytes
|
||||
are supported, rather than just 2, 4, and 8 bytes. The types may be aligned or
|
||||
unaligned.</p>
|
||||
|
||||
<p><b><a href="arithmetic.html">Endian arithmetic types</a> -</b> The application uses the provided endian
|
||||
arithmetic types, which supply the same operations as the built-in C++
|
||||
arithmetic types. All conversions are implicit. Arithmetic integer types with
|
||||
lengths of 1 through 8 bytes are supported, rather than just 2, 4, and 8 byte
|
||||
integers. The types may be aligned.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p>Boost Endian is a header-only library.</p>
|
||||
|
||||
<h2><a name="Choosing">Choosing</a> between endian conversion functions, endian buffer types,
|
||||
and endian arithmetic types</h2>
|
||||
|
||||
<p>Which approach to endianness is best depends on the interaction between
|
||||
approach characteristics and
|
||||
application needs.</p>
|
||||
|
||||
<p>The characteristics that differentiate the approaches are the endianness
|
||||
invariants, conversion explicitness, arithmetic operations, sizes available, and
|
||||
alignment requirements.</p>
|
||||
|
||||
<h3>Endianness invariants</h3>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Endian conversion functions</b> use objects of the ordinary C++ arithmetic
|
||||
types like <code>int</code> or <code>unsigned short</code> to hold values. That
|
||||
breaks the implicit invariant that the C++ language rules apply. The usual
|
||||
language rules only apply if the endianness of the object is currently set by
|
||||
the conversion functions to the native endianness for the platform. That can
|
||||
make it very hard to reason about complex logic flow, and result in difficult to
|
||||
find bugs.</p>
|
||||
|
||||
<p><b>Endian buffer and arithmetic types</b> hold values internally as arrays of
|
||||
characters with an invariant that the endianness of the array never changes.
|
||||
That makes these types easy to use and programs easy to maintain.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h3>Conversion explicitness</h3>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Endian conversion functions</b> and <b>buffer types</b> never perform
|
||||
implicit conversions. This gives users explicit control of when conversion
|
||||
occurs, and may help avoid unnecessary conversions.</p>
|
||||
|
||||
<p><b>Endian arithmetic types</b> perform conversion implicitly. That makes
|
||||
these types very easy to use, but can result in unnecessary conversions. Failure
|
||||
to hoist conversions out of inner loops can bring a performance penalty.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h3>Arithmetic operations</h3>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Endian conversion functions</b> do not supply arithmetic
|
||||
operations, but this is not a concern since this approach uses ordinary C++
|
||||
arithmetic types to hold values.</p>
|
||||
|
||||
<p><b>Endian buffer types</b> do not supply arithmetic operations. Although this
|
||||
approach avoids unnecessary conversions, it can result in the introduction of
|
||||
additional variables and confuse maintenance programmers.</p>
|
||||
|
||||
<p><b>Endian</b> <b>arithmetic types</b> do supply arithmetic operations. They
|
||||
are very easy to use if lots of arithmetic is involved.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h3>Sizes available</h3>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Endianness conversion functions</b> only support 1, 2, 4, and 8 byte
|
||||
integers. That's sufficient for many applications.</p>
|
||||
|
||||
<p><b>Endian buffer and arithmetic types</b> support 1, 2, 3, 4, 5, 6, 7, and 8
|
||||
byte integers. For an application where memory use or I/O speed is the limiting
|
||||
factor, using sizes tailored to application needs can be very useful.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h3>Alignments available</h3>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>Endianness conversion functions</b> only support aligned integer and
|
||||
floating-point types. That's sufficient for most applications.</p>
|
||||
|
||||
<p><b>Endian buffer and arithmetic types</b> support both aligned and unaligned
|
||||
integer and floating-point types. Unaligned types are rarely needed, but when
|
||||
needed they are often very useful and workarounds are painful. For example,</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Non-portable code like this:<blockquote>
|
||||
<p><code>struct S {<br>
|
||||
uint16_t a; // big endian<br>
|
||||
uint32_t b; // big endian<br>
|
||||
} __attribute__ ((packed));</code>
|
||||
</p></blockquote>
|
||||
<p>Can be replaced with portable code like this:</p>
|
||||
<blockquote>
|
||||
<p><code>struct S {<br>
|
||||
big_uint16_ut a;<br>
|
||||
big_uint32_ut b;<br>
|
||||
};</code>
|
||||
</p></blockquote>
|
||||
</blockquote>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h2>Built-in support for <a name="Intrinsic">Intrinsic</a>s</h2>
|
||||
<p>Supply compilers, including GCC, Clang, and Visual C++, supply built-in support for byte swapping intrinsics.
|
||||
The library uses these intrinsics when available since they may result in smaller and faster generated code, particularly for release
|
||||
builds.</p>
|
||||
<p>Defining <code>BOOST_ENDIAN_NO_INTRINSICS</code> will suppress use
|
||||
of the intrinsics. Useful when intrinsic headers such as
|
||||
<code>byteswap.h </code>are not being found on your platform.</p>
|
||||
<p>The macro <code>BOOST_ENDIAN_INTRINSIC_MSG</code> is defined as
|
||||
either <code>"no byte swap intrinsics"</code> or a string describing the
|
||||
particular set of intrinsics being used.</p>
|
||||
|
||||
<h2><a name="Performance">Performance</a></h2>
|
||||
|
||||
<p>Consider this problem:</p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p align="center"><i><b><a name="Example-1">Example 1</a></b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><b><i>Add 100 to a big endian value in a file, then write the
|
||||
result to a file</i> </b> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i><b>Endian arithmetic type approach</b></i></td>
|
||||
<td><i><b>Endian conversion function approach</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<pre>big_int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
x += 100;
|
||||
|
||||
... write x to a file ...
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
big_to_native_inplace(x);
|
||||
x += 100;
|
||||
native_to_big_inplace(x);
|
||||
|
||||
... write x to a file ...
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><b>There will be no performance difference between the two approaches in
|
||||
release builds,
|
||||
regardless of the native endianness of the machine.</b> That's because optimizing compilers will likely
|
||||
generate exactly the same code for each. That conclusion was confirmed by
|
||||
studying the generated assembly code for GCC and Visual C++. Furthermore, time
|
||||
spent doing I/O will determine the speed of this application.</p>
|
||||
|
||||
<p>Now consider a slightly different problem: </p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p align="center"><b><i><a name="Example-2">Example 2</a></i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><i><b>Add a million values to a big endian value in a file, then write the
|
||||
result to a file </b></i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i><b>Endian arithmetic type approach</b></i></td>
|
||||
<td><i><b>Endian conversion function approach</b></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<pre>big_int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
for (int32_t i = 0; i < 1000000; ++i)
|
||||
x += i;
|
||||
|
||||
... write x to a file ...
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>int32_t x;
|
||||
|
||||
... read into x from a file ...
|
||||
|
||||
big_to_native_inplace(x);
|
||||
|
||||
for (int32_t i = 0; i < 1000000; ++i)
|
||||
x += i;
|
||||
|
||||
native_to_big_inplace(x);
|
||||
|
||||
... write x to a file ...
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to
|
||||
big endian is done inside the loop. With the Endian conversion function
|
||||
approach, the user has ensured the conversions are done outside the loop, so the
|
||||
code may run more quickly on little endian platforms.</p>
|
||||
|
||||
<h3><a name="Timings">Timings</a> for Example 2 (conversion functions hoisted
|
||||
out of loop)</h3>
|
||||
<p>These tests were run against release builds on a circa 2012 4-core little endian X64 Intel Core i5-3570K
|
||||
CPU @ 3.40GHz under Windows 7.</p>
|
||||
|
||||
<p><b>Caveat emptor: The Windows CPU timer has very high granularity. Repeated
|
||||
runs of the same tests often yield considerably different results.</b></p>
|
||||
|
||||
<p>See <a href="../test/loop_time_test.cpp">loop_time_test.cpp</a> and
|
||||
<a href="../build/Jamfile.v2">Jamfile.v2</a> for the actual code and build
|
||||
setup.
|
||||
(For GCC 4.7, there are no 16-bit intrinsics, so they are emulated by using
|
||||
32-bit intrinsics.)</p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr><td colspan="6" align="center"><b><font size="2">GNU C++ version 4.7.0</font></b></td></tr>
|
||||
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: __builtin_bswap16, etc.</font></b></td></tr>
|
||||
<tr><td><b><font size="2">Test Case</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>arithmetic</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
|
||||
</tr>
|
||||
<tr><td><font size="2">16-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.37 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.83 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.09 s</font></td>
|
||||
<td align="right"><font size="2">0.83 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">1.09 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
|
||||
<td align="right"><b><font size="2">0.98 s</font></b></td>
|
||||
<td align="right"><b><font size="2">0.27 s</font></b></td></tr>
|
||||
<tr><td><font size="2">32-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.28 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">3.82 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">3.82 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.65 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">17.53 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">17.52 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
|
||||
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
|
||||
<tr><td><b><font size="2">Test Case</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>arithmetic</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
|
||||
</tr>
|
||||
<tr><td><font size="2">16-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.95 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.83 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.19 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">1.20 s</font></td>
|
||||
<td align="right"><font size="2">0.81 s</font></td></tr>
|
||||
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
|
||||
<td align="right"><b><font size="2">0.97 s</font></b></td>
|
||||
<td align="right"><b><font size="2">0.28 s</font></b></td></tr>
|
||||
<tr><td><font size="2">32-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td>
|
||||
<td align="right"><font size="2">0.28 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">4.10 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">4.10 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.64 s</font></td>
|
||||
<td align="right"><font size="2">0.42 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">17.52 s</font></td>
|
||||
<td align="right"><font size="2">0.42 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">17.52 s</font></td>
|
||||
<td align="right"><font size="2">0.41 s</font></td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p><b>Comment:</b> Note that the <b><font size="2">32-bit aligned big endian </font></b>
|
||||
timings are the same with or without intrinsics turned on. Presumably the
|
||||
optimizer is recognizing the byte swapping and applying the intrinsics itself.</p>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr><td colspan="6" align="center"><b><font size="2">Microsoft Visual C++ version 11.0</font></b></td></tr>
|
||||
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.</font></b></td></tr>
|
||||
<tr><td><b><font size="2">Test Case</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>type</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
|
||||
</tr>
|
||||
<tr><td><font size="2">16-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">0.83 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td>
|
||||
<td align="right"><font size="2">0.50 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.37 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">1.37 s</font></td>
|
||||
<td align="right"><font size="2">0.50 s</font></td></tr>
|
||||
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
|
||||
<td align="right"><b><font size="2">0.81 s</font></b></td>
|
||||
<td align="right"><b><font size="2">0.50 s</font></b></td></tr>
|
||||
<tr><td><font size="2">32-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">2.98 s</font></td>
|
||||
<td align="right"><font size="2">0.53 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">3.00 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.33 s</font></td>
|
||||
<td align="right"><font size="2">0.33 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.34 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">7.05 s</font></td>
|
||||
<td align="right"><font size="2">0.33 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">7.11 s</font></td>
|
||||
<td align="right"><font size="2">0.31 s</font></td></tr>
|
||||
|
||||
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
|
||||
<tr><td><b><font size="2">Test Case</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>type</font></b></td>
|
||||
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
|
||||
</tr>
|
||||
<tr><td><font size="2">16-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">0.83 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">1.36 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">16-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">1.37 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
|
||||
<td align="right"><b><font size="2">3.42 s</font></b></td>
|
||||
<td align="right"><b><font size="2">0.50 s</font></b></td></tr>
|
||||
<tr><td><font size="2">32-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td>
|
||||
<td align="right"><font size="2">0.51 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">2.93 s</font></td>
|
||||
<td align="right"><font size="2">0.50 s</font></td></tr>
|
||||
<tr><td><font size="2">32-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">2.95 s</font></td>
|
||||
<td align="right"><font size="2">0.50 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned big endian</font></td>
|
||||
<td align="right"><font size="2">5.99 s</font></td>
|
||||
<td align="right"><font size="2">0.33 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit aligned little endian</font></td>
|
||||
<td align="right"><font size="2">0.33 s</font></td>
|
||||
<td align="right"><font size="2">0.33 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned big endian</font></td>
|
||||
<td align="right"><font size="2">7.02 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
<tr><td><font size="2">64-bit unaligned little endian</font></td>
|
||||
<td align="right"><font size="2">7.02 s</font></td>
|
||||
<td align="right"><font size="2">0.27 s</font></td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<h3><a name="Conclusions">Conclusions</a></h3>
|
||||
|
||||
<p>When program logic dictates many more conversions for the Endian arithmetic
|
||||
approach than the Endian conversion function approach (<a href="#Example-2">example
|
||||
2</a>):</p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><b>There may be a considerable performance difference. </b>If machine endianness differs from the
|
||||
desired endianness, the Endian arithmetic approach must do the byte reversal many
|
||||
times while the Endian conversion approach only does the reversal once. But if
|
||||
the endianness is the same, there is no conversion with either approach and no
|
||||
conversion code is generated for typical release builds.</p>
|
||||
|
||||
<p><b>Whether or not compiler byte swap intrinsics are explicitly available has little
|
||||
impact on GCC but a lot of impact on Visual C++, for the tested compiler
|
||||
versions.</b> Yet another example of why actual timing tests are needed to
|
||||
determine if some coding technique has significant impact on performance.</p>
|
||||
|
||||
<p><b>Unaligned types are much slower that aligned types, regardless of
|
||||
endianness considerations.</b> Instead of single instruction register loads and
|
||||
stores, multiple instructions are required.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h2>Overall <a name="FAQ">FAQ</a></h2>
|
||||
|
||||
<p><b>Is the implementation header only?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>Yes.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p><b>Does the implementation use compiler intrinsic built-in byte swapping?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>Yes, if available. See <a href="#Intrinsic">Intrinsic built-in support</a>.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p><b>Why bother with endianness?</b></p>
|
||||
<blockquote>
|
||||
<p>Binary data portability is the primary use case.</p>
|
||||
</blockquote>
|
||||
<p><b>Does endianness have any uses outside of portable binary file or network
|
||||
I/O formats?</b> </p>
|
||||
<blockquote>
|
||||
<p>Using the unaligned integer types to save internal or external
|
||||
memory space is a minor secondary use case.</p>
|
||||
</blockquote>
|
||||
<p><b>Why bother with binary I/O? Why not just use C++ Standard Library stream
|
||||
inserters and extractors?</b></p>
|
||||
<blockquote>
|
||||
<p>Data interchange formats often specify binary arithmetic data.</p>
|
||||
<p>Binary arithmetic data is smaller and therefore I/O is faster and file sizes
|
||||
are smaller. Transfer between systems is less expensive.</p>
|
||||
<p>Furthermore, binary arithmetic data is of fixed size, and so fixed-size disk
|
||||
records are possible without padding, easing sorting and allowing direct access.
|
||||
Disadvantages, such as the inability to use text utilities on the resulting
|
||||
files, limit usefulness to applications where the binary I/O advantages are
|
||||
paramount.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Which is better, big-endian or little-endian?</b></p>
|
||||
<blockquote>
|
||||
<p>Big-endian tends to be preferred in a networking environment and is a bit
|
||||
more of an industry standard, but little-endian may be preferred for
|
||||
applications that run primarily on x86, x64, and other little-endian
|
||||
CPU's. The <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article
|
||||
gives more pros and cons.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Why are only big, little, and native endianness supported?</b></p>
|
||||
<blockquote>
|
||||
<p>These are the only endian schemes that have any practical value today. PDP-11
|
||||
and the other middle endian approaches are interesting historical curiosities
|
||||
but have no relevance to today's C++ developers.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>What are the limitations of floating point support?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>The only supported types are four-byte <code>float</code> and eight-byte
|
||||
<code>double</code>. Even after endianness has been accounted for, floating
|
||||
point values will not be portable between systems that use different floating
|
||||
point formats. Systems where integer endianness differs from floating point
|
||||
endianness are not supported.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p><b>What are the limitations of integer support?</b></p>
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p>Tests have only been
|
||||
performed on machines that use two's complement arithmetic. The Endian
|
||||
conversion functions support 16, 32, and 64-bit aligned integers only. The
|
||||
Endian types support 8, 16, 24, 32, 40, 48, 56, and 64-bit unaligned integers
|
||||
and 16, 32, and 64-bit aligned integers.</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="Release-history">Release history</a></h2>
|
||||
<h3>Changes since formal review</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<p>The endian types have been decomposed into endian buffer types
|
||||
and endian arithmetic types, as requested. The arithmetic types derive from
|
||||
the buffer types.</li>
|
||||
<li>
|
||||
<p>Headers have been renamed to <code>endian/arithmetic.hpp</code> and
|
||||
<code>endian/conversion.hpp</code>. <code>endian/buffers.hpp</code> has been
|
||||
added.
|
||||
Infrastructure file names were changed accordingly.</li>
|
||||
<li>
|
||||
<p>The endian buffer and arithmetic types and endian conversion functions now support 32-bit (<code>float)</code> and
|
||||
64-bit <code>(double)</code> floating point, as requested.</li>
|
||||
<li>The endian types now have stream inserter and extractor templates, as
|
||||
requested.</li>
|
||||
<li>Both the endian types and endian conversion functions now support UDTs, as requested.</li>
|
||||
<li>The endian type aliases have been renamed,
|
||||
using a naming pattern that is consistent for both integer and floating point, .</li>
|
||||
<li>The conversion functions have been much revised,
|
||||
refactored, and otherwise improved based on review comments.<ul>
|
||||
<li>Functions have been renamed to clarify their functionality.</li>
|
||||
<li>Both return-by-value and modify-in-place interfaces are provided, as
|
||||
requested.</li>
|
||||
<li>In addition to the named-endianness functions, functions that perform
|
||||
compile-time (via template) and run-time (via function argument) dispatch
|
||||
are now provided, as requested.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in functions
|
||||
are used in the implementation where appropriate, as requested.</li>
|
||||
<li>For the endian types, the implementation uses the endian conversion functions,
|
||||
and thus the intrinsics,
|
||||
as requested.</li>
|
||||
<li><code>order::native</code> is now a synonym for <code>order::big</code>
|
||||
or <code>order::little</code> according to the endianness of the platform, as
|
||||
requested. This reduces the number of template specializations required.</li>
|
||||
<li><code>endian_reverse()</code> overloads for <code>int8_t</code> and <code>
|
||||
uint8_t</code> have been added for improved generality. (Pierre Talbot)</li>
|
||||
<li>Overloads of <code>endian_reverse_inplace()</code> have been replaced with a single <code>
|
||||
endian_reverse_inplace()</code> template. (Pierre Talbot)</li>
|
||||
<li>C++11 features such as <code>noexcept</code> are now used, while still
|
||||
supporting C++03 compilers.</li>
|
||||
<li>Headers have been reorganized to make them easier to read,
|
||||
with a synopsis at the front and implementation following, as requested.</li>
|
||||
<li>Documentation has been revised to address most, but not all, concerns
|
||||
raised during formal review.</li>
|
||||
<li>Acknowledgements have been updated.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
<p>Comments and suggestions were received from Adder, Benaka Moorthi,
|
||||
Christopher Kohlhoff, Cliff Green, Daniel James, Gennaro Proto, Giovanni Piero
|
||||
Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jeff Flinn, John Filo, John
|
||||
Maddock, Kim Barrett, Marsh Ray, Martin Bonner, Mathias Gaunard, Matias
|
||||
Capeletto, Neil Mayhew, Paul Bristow, Pierre Talbot, Phil Endecott, Pyry Jahkola,
|
||||
Rene Rivera, Robert Stewart, Roland Schwarz, Scott McMurray, Sebastian Redl, Tim
|
||||
Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and
|
||||
Vitaly Budovski,.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->15 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38643" --></p>
|
||||
<p>© Copyright Beman Dawes, 2011, 2013</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,109 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Endian Mini-Review</title>
|
||||
</head>
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
<body>
|
||||
|
||||
<p>Here is what needs to be done to get the library ready for a mini-review:
|
||||
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
<p><b>Common use case scenarios should be developed.</b></p>
|
||||
<blockquote>
|
||||
|
||||
<p> </p>
|
||||
</blockquote>
|
||||
<p><b>Example programs should be developed for the common use case scenarios.</b></p>
|
||||
<blockquote>
|
||||
<p> </p>
|
||||
</blockquote>
|
||||
<p><b>Documentation should illuminate the differences between endian
|
||||
integer/float type and endian conversion approaches to the common use
|
||||
case scenarios, and provide guidelines for choosing the most appropriate
|
||||
approach in user's applications.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. See <a href="index.html#Choosing">Choosing between
|
||||
<span style="background-color: #FFFF00">endian types</span> and
|
||||
endian conversion functions</a>.</p>
|
||||
</blockquote>
|
||||
<p><b>Conversion functions supplying results via return should be provided.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. See <a href="conversion.html">conversion docs</a>.</p>
|
||||
</blockquote>
|
||||
<p><b>Platform specific performance enhancements such as use of compiler intrinsics or relaxed alignment requirements should be supported.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in
|
||||
functions are used in the implementation where appropriate, as requested. See
|
||||
<a href="index.html#Intrinsic">Built-in support for Intrinsics</a>. See
|
||||
<a href="index.html#Timings">Timings for Example 2</a> to gauge the impact of
|
||||
intrinsics.</p>
|
||||
</blockquote>
|
||||
<p><b>Endian integer (and floating) types should be implemented via the
|
||||
conversion functions. If that can't be done efficiently, consideration
|
||||
should be given to expanding the conversion function signatures to
|
||||
resolve the inefficiencies.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. For the endian types, the implementation uses the endian conversion
|
||||
functions, and thus the intrinsics, as requested.</p>
|
||||
</blockquote>
|
||||
<p><b>Benchmarks that measure performance should be provided. It should be
|
||||
possible to compare platform specific performance enhancements against
|
||||
portable base implementations, and to compare endian integer approaches
|
||||
against endian conversion approaches for the common use case scenarios.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. See <a href="index.html#Timings">Timings for Example 2</a>. The <code>endian/test</code> directory
|
||||
also contains several addional benchmark and speed test programs.</p>
|
||||
</blockquote>
|
||||
<p><b>Float (32-bits) and double (64-bits) should be supported. IEEE 754 is
|
||||
the primary use case.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. The <a href="types.html">endian types</a> and
|
||||
<a href="conversion.html">endian conversion</a> functions now support 32-bit (<code>float)</code>
|
||||
and 64-bit <code>(double)</code> floating point, as requested.</p>
|
||||
</blockquote>
|
||||
<p><b>Support for user defined types (UDTs) is desirable, and should be
|
||||
provided where there would be no conflict with the other concerns.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. See <a href="conversion.html#Requirements">conversion requirements</a>.</p>
|
||||
</blockquote>
|
||||
<p><b>There is some concern that endian integer/float arithmetic operations
|
||||
might used inadvertently or inappropriately. The impact of adding an endian_buffer
|
||||
class without arithmetic operations should be investigated.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. The endian types have been decomposed into class template <code>
|
||||
<a href="buffers.html">endian_buffer</a></code> and class template <code>
|
||||
<a href="arithmetic.html">endian_arithmetic</a></code>. Class
|
||||
<code>endian_buffer</code> is a public base class for <code>endian_arithmetic</code>,
|
||||
and can also be used by users as a stand-alone class.</p>
|
||||
</blockquote>
|
||||
<p><b>Stream insertion and extraction of the endian integer/float types should
|
||||
be documented and included in the test coverage.</b></p>
|
||||
<blockquote>
|
||||
<p>Done. See <a href="types.html#Stream-inserter">Stream inserter</a> and
|
||||
<a href="types.html#Stream-extractor">Stream extractor</a>.</p>
|
||||
</blockquote>
|
||||
<p><b>Binary I/O support that was investigated during development of the Endian
|
||||
library should be put up for mini-review for inclusion in the Boost I/O
|
||||
library.</b></p>
|
||||
|
||||
<blockquote>
|
||||
<p> </p>
|
||||
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38642" --></p>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2014</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
Windows
|
||||
-------
|
||||
|
||||
Prerequisites
|
||||
|
||||
Boost libraries available in boost-root\stage\lib. Example:
|
||||
|
||||
cd boost-root
|
||||
.\bootstrap
|
||||
.\b2 --with-system --with-chrono --with-timer link=shared stage
|
||||
|
||||
The provided Visual Studio solution (endian/test/msvc/endian.sln) has a property page
|
||||
(endian/test/msvc/common.prop) with these Common Properties set (do not include the
|
||||
double quotes):
|
||||
|
||||
VC++ Directores|Executable Directories: prefix default value with "..\..\..\..\..\stage\lib;"
|
||||
(Click "Inherit from parent or project defaults" if not checked)
|
||||
|
||||
C/C++|General|Additional Include Directories: prefix default value with "..\..\..\..\..\stage\lib;"
|
||||
|
||||
Linker|General|Additional Library Directories: prefix default value with "..\..\..\..\..\stage\lib;"
|
||||
|
||||
C/C++|Preprocessor: prefix default value with "BOOST_ALL_DYN_LINK;"
|
||||
|
||||
IMPORTANT: If Preprocessor macros are supplied via a common property page,
|
||||
<inherit from parent or project defaults> must be set for each project!
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
Copyright Beman Dawes, 2013
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
See http://www.boost.org/LICENSE_1_0.txt
|
@ -1,13 +0,0 @@
|
||||
|
||||
body
|
||||
{
|
||||
font-family: sans-serif;
|
||||
max-width: 6.5in;
|
||||
font-size: 85%;
|
||||
}
|
||||
ins {background-color: #CCFFCC;}
|
||||
del {background-color: #FFCACA;}
|
||||
pre {background-color: #D7EEFF; font-size: 100%;}
|
||||
code {font-size: 110%;}
|
||||
table{font-size: 100%;}
|
||||
|
@ -1,232 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Endian Library Do List</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Endian Library TODO List</h1>
|
||||
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->15 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38643" --></p>
|
||||
|
||||
<p><b>August 12, 2014: The many items that have been completed should be
|
||||
removed, after verifying that they are in fact taken care of.</b></p>
|
||||
<h2>To Do</h2>
|
||||
<ul>
|
||||
<li>Develop the use-cases example programs, using plain integers and UDT's.</li>
|
||||
<li>Review UDT examples.</li>
|
||||
<li>Review buffer stream extractors and inserters, and how they work for
|
||||
arithmetic types. TEST. Make sure nothing got dropped on the floor during
|
||||
buffer decomposition.</li>
|
||||
<li><span style="background-color: #FFFF00">Run inspect.</span>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Format Review Comments</h2>
|
||||
<h3 dir="ltr">Votes</h3>
|
||||
<ul>
|
||||
<li dir="ltr">
|
||||
<p dir="ltr">John Filo - "Absolutely. I'd like to see support for float and
|
||||
double, but<br>
|
||||
even without those additions, I still vote yes." "For those who deal with
|
||||
non-native endian data, this library is<br>
|
||||
extremely useful. It automatically eliminates a whole class of common<br>
|
||||
programming errors when dealing with such data."<br>
|
||||
</li>
|
||||
<li dir="ltr">
|
||||
<p dir="ltr">Hartmut Kaiser - "Even if this is not a full review, I would like
|
||||
to vote YES to include this <br>
|
||||
library into Boost.
|
||||
<p>Boost.Spirit is using (and shipping) with an older version of this library
|
||||
<br>
|
||||
for several years now and we never had any problems with its usage in <br>
|
||||
Spirit. It is used as the underlying framework for the binary parsers and <br>
|
||||
generators and it is functioning as advertised.</p>
|
||||
<p>As a quick test I replaced the internal (older) version of Boost.Endian in
|
||||
<br>
|
||||
Spirit with the reviewed version. All of Spirits regression tests still <br>
|
||||
pass. "<br>
|
||||
</li>
|
||||
<li dir="ltr">
|
||||
<p dir="ltr">Robert Stewart - "There are issues that keep me from saying yes
|
||||
at this time. There are too many suggested variations and ideas under
|
||||
consideration to accept the library in its present state. However, a
|
||||
mini-review should be sufficient to evaluate the final form, once Beman
|
||||
determines a course of action, and determine whether to accept it or not."<br>
|
||||
</li>
|
||||
<li dir="ltr">
|
||||
<p dir="ltr">Tim Blechmann - "the library should be accepted, if<br>
|
||||
<br>
|
||||
(a) the interface of the conversion functions is changed<br>
|
||||
(b) the performance can be improved<br>
|
||||
(c) the documentation integrates better with the rest of the boost<br>
|
||||
documentation."<br>
|
||||
</li>
|
||||
<li dir="ltr">
|
||||
<p dir="ltr">Vicente J. Botet Escriba - "No in its current state.<br>
|
||||
Once the library takes in account the requested modification (that Beman has
|
||||
already accepted) a mini-review will be necessary to improve the library
|
||||
before release."</li>
|
||||
</ul>
|
||||
<h3>Executive summary</h3>
|
||||
<ul>
|
||||
<li>Common use case scenarios should be developed.</li>
|
||||
<li>Example programs should be developed for the common use case scenarios.</li>
|
||||
<li>Documentation should illuminate the differences between endian
|
||||
integer/float type and endian conversion approaches to the common use case
|
||||
scenarios, and provide guidelines for choosing the most appropriate approach
|
||||
for user's applications.</li>
|
||||
<li>Conversion functions supplying results via <code>return</code> should be
|
||||
provided.</li>
|
||||
<li>Platform specific performance enhancements such as use of compiler
|
||||
intrinsics or relaxed alignment requirements should be supported.</li>
|
||||
<li>Endian integer (and floating) types should be implemented via the
|
||||
conversion functions. If that can't be done efficiently, consideration should
|
||||
be given to expanding the conversion function signatures to resolve the
|
||||
inefficiencies.</li>
|
||||
<li>Benchmarks that measure performance should be provided. It should be
|
||||
possible to compare platform specific performance enhancements against
|
||||
portable base implementations, and to compare endian integer approaches
|
||||
against endian conversion approaches for the common use case scenarios.</li>
|
||||
<li>Float (32-bits) and double (64-bits) should be supported. IEEE 754 is the
|
||||
primary use case.</li>
|
||||
<li>Support for user defined types (UDTs) is desirable, and should be
|
||||
supported where there would be no conflict with the other concerns.</li>
|
||||
<li>There is some concern that endian integer/float arithmetic operations
|
||||
might used
|
||||
inadvertently or inappropriately. The impact of adding an endian_buffer class without arithmetic
|
||||
operations should be investigated.</li>
|
||||
<li>Stream insertion and extraction of the endian integer/float types should
|
||||
be documented and included in the test coverage.</li>
|
||||
<li>Binary I/O support that was investigated during development of the Endian
|
||||
library should be put up for min-review for inclusion in the Boost I/O
|
||||
library.</li>
|
||||
</ul>
|
||||
<h3>Docs</h3>
|
||||
<ul>
|
||||
<li>Document use of endian integers with stream inserters and extractors.</li>
|
||||
<li>Conversion in note mention similarity to htonl() , etc.</li>
|
||||
<li>Conversion: add discussion of alignment, packing, etc. Bottom line; use at
|
||||
your own risk. Use Phil's example:<br>
|
||||
struct S {<br>
|
||||
uint16_t a;<br>
|
||||
uint32_t b;<br>
|
||||
} __attribute__ ((packed));</li>
|
||||
<li>Requirements for template parameters. </li>
|
||||
<li>UDTs<ul>
|
||||
<li>Integers</li>
|
||||
<li>Conversion</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Distinguish use cases and recommendations for which approach (integers vs
|
||||
conversion) is appropriate.<ul>
|
||||
<li><a href="http://lists.boost.org/Archives/boost/2011/09/185698.php">
|
||||
http://lists.boost.org/Archives/boost/2011/09/185698.php</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>> section `experience': this section gives no insights for people who use
|
||||
or<br>
|
||||
> read the code. it mainly tells: "we are not the first and the domain of the<br>
|
||||
> library is important.". imo this section can be removed (maybe the part that<br>
|
||||
> it is not related to any c library can go to the `design considerations'<br>
|
||||
><br>
|
||||
> section "motivating use cases": this is more a marketing blurb/testimonial.<br>
|
||||
> maybe this could be changed to a section about possible use cases, listing<br>
|
||||
> `communicating between different devices' and `reading/writing of binary
|
||||
file<br>
|
||||
> formats'.</li>
|
||||
<li>one other point ... the help file seems to directly link to the c++
|
||||
headers.<br>
|
||||
this should be changed:<br>
|
||||
<br>
|
||||
* some browsers (at least chromium) will not display the header when clicking<br>
|
||||
the link, but will save them on disk.<br>
|
||||
<br>
|
||||
* providing a direct link to the source code from the docs implies that the<br>
|
||||
user will get some information that are necessary to use the library by<br>
|
||||
reading the sources. imo, this is not the case for using boost.endian.<br>
|
||||
<br>
|
||||
* if a user opens integer.hpp, the first 60 lines just contain copyright, some<br>
|
||||
historical notes, compiler-specific stuff, includes and ifdefs. imo, this is<br>
|
||||
the implementation part, which should not be exposed to a user.<br>
|
||||
<br>
|
||||
so i'd suggest to completely remove the links to the c++ headers.<br>
|
||||
</li>
|
||||
<li>
|
||||
<div class="im">
|
||||
> explaining the other builting types are not considered. Why only
|
||||
big/little<br>
|
||||
> endianness has been taken in account?</div>
|
||||
<p>I'll add FAQ and/or add more entries to the final docs.<br>
|
||||
<br>
|
||||
Only big/little endianness is taken into account because these are the<br>
|
||||
only endian schemes that have any practical value. All the others are<br>
|
||||
just historical curiosities.</li>
|
||||
</ul>
|
||||
<h3>Code</h3>
|
||||
<p>Also change docs if applicable.</p>
|
||||
<ul>
|
||||
<li><span style="background-color: #FFCCFF">Beman: TODO</span><span style="background-color: #FFCCFF">:
|
||||
</span><span style="background-color: #FFCCFF">Google</span><span style="background-color: #FFCCFF">
|
||||
"unaligned integer", look at various entries. For example, http://</span><span style="background-color: #FFCCFF">infocenter.arm.com</span><span style="background-color: #FFCCFF">/help/</span><span style="background-color: #FFCCFF">index.jsp?topic</span><span style="background-color: #FFCCFF">=/</span><span style="background-color: #FFCCFF">com.arm.doc.faqs</span><span style="background-color: #FFCCFF">/ka3544.html</span></li>
|
||||
<li>Beman: Some platforms (compiler/processor taken together) don't require
|
||||
alignment for the conversion functions if code is inlined, although speed may
|
||||
suffer. (test to verify this assertion). On those platforms, conversion
|
||||
functions (perhaps in-place) can be used to implement unaligned integers.<ul>
|
||||
<li>Microsoft <a href="http://msdn.microsoft.com/en-us/library/ms253978.aspx">
|
||||
UNALIGNED / __unaligned</a> keywords for pointers. Also
|
||||
<a href="http://msdn.microsoft.com/en-us/library/ms253935.aspx">Packing
|
||||
Structures</a>.</li>
|
||||
<li>GCC
|
||||
<a href="http://www.mailinglistarchive.com/gcc@gcc.gnu.org/msg21079.html">
|
||||
http://www.mailinglistarchive.com/gcc@gcc.gnu.org/msg21079.html</a></li>
|
||||
<li>Intel performs well on simple unaligned test. See
|
||||
<a href="../test/unaligned_test.cpp">../test/unaligned_test.cpp</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Beman: Does the use of the unrolling templates get in the way of processor
|
||||
specific optimization code?</li>
|
||||
<li>Test use of endian integers with stream inserters and extractors.</li>
|
||||
<li>Continue work on benchmarks and timings. Consider using use-case example
|
||||
programs as benchmarks.</li>
|
||||
<li dir="ltr">
|
||||
<div class="im">
|
||||
> The library should provide in addition endian conversion functions that
|
||||
have<br>
|
||||
> the endiannes as template parameters to make possible generic functions.</div>
|
||||
<p dir="ltr">Compile time dispatch on an endianness enum was also requested in<br>
|
||||
another review. That's fine with me, but I haven't had a chance to<br>
|
||||
figure out the interface details.</li>
|
||||
</ul>
|
||||
<h3>Infrastructure</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<div class="im">
|
||||
> endian_operations_test.cpp and endian_in_union_test.cpp ... maybe rename
|
||||
from<br>
|
||||
> _test.cpp to _compile_test.cpp? they don't seem to do any run-time tests.
|
||||
they<br>
|
||||
> also should not include <cassert> since no assertion statement is needed,
|
||||
this<br>
|
||||
> might speed up the compilation time of the testsuite by something like
|
||||
50ms ;)</div>
|
||||
<p>Will do.</li>
|
||||
<li>Make the bin() functionality available</li>
|
||||
</ul>
|
||||
|
||||
<p>* I'm only willing to provide conversion.hpp FP support. Providing<br>
|
||||
types that mimic FP types is far beyond my knowledge of how to deal<br>
|
||||
with floating point's notorious arithmetic issues.</p>
|
||||
<p>Support IEEE754 format (32 bit, 64 bit) only.</p>
|
||||
<hr>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,4 +1,4 @@
|
||||
// endian/example/conversion_use_case.cpp
|
||||
// endian/example/conversion_use_case.cpp
|
||||
|
||||
// Copyright Beman Dawes 2014
|
||||
|
||||
@ -44,8 +44,8 @@ int main()
|
||||
|
||||
for (auto &out_rec : recs) // write each record
|
||||
{
|
||||
out_rec.balance = boost::endian::native_to_big(rec.balance); // reverse if needed
|
||||
out_rec.balance = boost::endian::native_to_big(out_rec.balance); // reverse if needed
|
||||
out.write((const char*)&out_rec, sizeof(out_rec));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format. Why the designer
|
||||
// decided to mix big and little endians in the same file is not known. But
|
||||
@ -27,10 +27,10 @@ namespace
|
||||
|
||||
struct header
|
||||
{
|
||||
big_int32_buf_t file_code;
|
||||
big_int32_buf_t file_length;
|
||||
little_int32_buf_t version;
|
||||
little_int32_buf_t shape_type;
|
||||
big_int32_buf_at file_code;
|
||||
big_int32_buf_at file_length;
|
||||
little_int32_buf_at version;
|
||||
little_int32_buf_at shape_type;
|
||||
};
|
||||
|
||||
const char* filename = "test.dat";
|
||||
@ -38,10 +38,10 @@ namespace
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
|
||||
|
||||
header h;
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof(header);
|
||||
h.version = 1;
|
||||
@ -54,7 +54,7 @@ int main(int, char* [])
|
||||
// does bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
|
||||
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
|
@ -17,23 +17,24 @@ using namespace boost::endian;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using boost::int32_t;
|
||||
using boost::int64_t;
|
||||
|
||||
namespace user
|
||||
{
|
||||
class UDT
|
||||
{
|
||||
public:
|
||||
UDT() : id_(0), value_(0.0) {desc_[0] = '\0';}
|
||||
UDT(int32_t id, float value, const char* desc) : id_(id), value_(value)
|
||||
UDT() : id_(0), value_(0) {desc_[0] = '\0';}
|
||||
UDT(int32_t id, int64_t value, const char* desc) : id_(id), value_(value)
|
||||
{
|
||||
std::strncpy(desc_, desc, sizeof(desc_)-1);
|
||||
desc_[sizeof(desc_)-1] = '\0';
|
||||
}
|
||||
int32_t id() const {return id_;}
|
||||
float value() const {return value_;}
|
||||
int64_t value() const {return value_;}
|
||||
const char* desc() const {return desc_;}
|
||||
void id(int32_t x) {id_ = x;}
|
||||
void value(float v) {value_ = v;}
|
||||
void value(int64_t v) {value_ = v;}
|
||||
void desc(const char* s)
|
||||
{
|
||||
std::strncpy(desc_, s, sizeof(desc_)-1);
|
||||
@ -44,7 +45,7 @@ namespace user
|
||||
|
||||
private:
|
||||
int32_t id_;
|
||||
float value_;
|
||||
int64_t value_;
|
||||
char desc_[56]; // '/0'
|
||||
};
|
||||
|
||||
@ -57,7 +58,7 @@ namespace user
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
user::UDT x(1, 1.2345f, "Bingo!");
|
||||
user::UDT x(1, 123456789012345LL, "Bingo!");
|
||||
|
||||
//cout << std::hex;
|
||||
cout << "(1) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl;
|
||||
|
@ -121,7 +121,7 @@ using std::endl;
|
||||
// Recommended approach when conversion time is a concern
|
||||
//
|
||||
// Conversion time is a concert with this application because (1) any conversions
|
||||
// performed in the loop will consume a great deal of time and because (2)
|
||||
// performed in the loop will consume a great deal of time and because (2)
|
||||
// computation time will be much greater than I/O time.
|
||||
|
||||
{
|
||||
|
13
include/boost/endian.hpp
Normal file
13
include/boost/endian.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef BOOST_ENDIAN_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_ENDIAN_HPP_INCLUDED
|
@ -2,6 +2,7 @@
|
||||
|
||||
// (C) Copyright Darin Adler 2000
|
||||
// (C) Copyright Beman Dawes 2006, 2009, 2014
|
||||
// (C) Copyright Peter Dimov 2019
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
@ -18,36 +19,27 @@
|
||||
|
||||
// TODO: When a compiler supporting constexpr becomes available, try possible uses.
|
||||
|
||||
#ifndef BOOST_ENDIAN_HPP
|
||||
#define BOOST_ENDIAN_HPP
|
||||
#ifndef BOOST_ENDIAN_ARITHMETIC_HPP
|
||||
#define BOOST_ENDIAN_ARITHMETIC_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_ENDIAN_LOG
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef/detail/endian_compat.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
#include <boost/endian/detail/cover_operators.hpp>
|
||||
#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/detail/scoped_enum_emulation.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <iosfwd>
|
||||
#include <climits>
|
||||
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
# if CHAR_BIT != 8
|
||||
# error Platforms with CHAR_BIT != 8 are not supported
|
||||
# endif
|
||||
@ -58,7 +50,8 @@
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
// g++ pre-4.6 does not support unrestricted unions, but we have no Config macro for that
|
||||
# if (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || BOOST_WORKAROUND(BOOST_GCC, < 40600)) && defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
# define BOOST_ENDIAN_NO_CTORS
|
||||
# endif
|
||||
|
||||
@ -75,364 +68,303 @@ namespace boost
|
||||
namespace endian
|
||||
{
|
||||
|
||||
#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
BOOST_SCOPED_ENUM_START(order)
|
||||
{
|
||||
big, little,
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
native = big
|
||||
# else
|
||||
native = little
|
||||
# endif
|
||||
}; BOOST_SCOPED_ENUM_END
|
||||
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
#endif
|
||||
|
||||
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(align) A = align::no>
|
||||
BOOST_SCOPED_ENUM(align) Align = align::no>
|
||||
class endian_arithmetic;
|
||||
|
||||
// big endian floating point aligned types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::yes> big_float32_t;
|
||||
typedef endian_arithmetic<order::big, double, 64, align::yes> big_float64_t;
|
||||
|
||||
// little endian floating point aligned types
|
||||
typedef endian_arithmetic<order::little, float, 32, align::yes> little_float32_t;
|
||||
typedef endian_arithmetic<order::little, double, 64, align::yes> little_float64_t;
|
||||
|
||||
// big endian floating point unaligned types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::no> big_float32_ut;
|
||||
typedef endian_arithmetic<order::big, double, 64, align::no> big_float64_ut;
|
||||
|
||||
// little endian floating point unaligned types
|
||||
typedef endian_arithmetic<order::little, float, 32, align::no> little_float32_ut;
|
||||
typedef endian_arithmetic<order::little, double, 64, align::no> little_float64_ut;
|
||||
|
||||
// big endian signed integer aligned types
|
||||
typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_t;
|
||||
typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_t;
|
||||
typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_t;
|
||||
typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at;
|
||||
typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at;
|
||||
typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at;
|
||||
typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at;
|
||||
|
||||
// big endian unsigned integer aligned types
|
||||
typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_t;
|
||||
typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_t;
|
||||
typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_t;
|
||||
typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at;
|
||||
typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at;
|
||||
typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at;
|
||||
typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at;
|
||||
|
||||
// little endian signed integer aligned types
|
||||
typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_t;
|
||||
typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_t;
|
||||
typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_t;
|
||||
typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at;
|
||||
typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at;
|
||||
typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at;
|
||||
typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at;
|
||||
|
||||
// little endian unsigned integer aligned types
|
||||
typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_t;
|
||||
typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_t;
|
||||
typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_t;
|
||||
typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at;
|
||||
typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at;
|
||||
typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at;
|
||||
typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at;
|
||||
|
||||
// aligned floating point types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::yes> big_float32_at;
|
||||
typedef endian_arithmetic<order::big, double, 64, align::yes> big_float64_at;
|
||||
typedef endian_arithmetic<order::little, float, 32, align::yes> little_float32_at;
|
||||
typedef endian_arithmetic<order::little, double, 64, align::yes> little_float64_at;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
// big endian signed integer unaligned types
|
||||
typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_ut;
|
||||
typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_ut;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_ut;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_ut;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_ut;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_ut;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_ut;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_ut;
|
||||
typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t;
|
||||
typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t;
|
||||
typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t;
|
||||
typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t;
|
||||
|
||||
// big endian unsigned integer unaligned types
|
||||
typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_ut;
|
||||
typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t;
|
||||
typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t;
|
||||
typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t;
|
||||
typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t;
|
||||
|
||||
// little endian signed integer unaligned types
|
||||
typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_ut;
|
||||
typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_ut;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_ut;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_ut;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_ut;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_ut;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_ut;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_ut;
|
||||
typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t;
|
||||
typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t;
|
||||
typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t;
|
||||
typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t;
|
||||
|
||||
// little endian unsigned integer unaligned types
|
||||
typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_ut;
|
||||
typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t;
|
||||
typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t;
|
||||
typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t;
|
||||
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
// native endian signed integer unaligned types
|
||||
typedef big_int8_ut native_int8_ut;
|
||||
typedef big_int16_ut native_int16_ut;
|
||||
typedef big_int24_ut native_int24_ut;
|
||||
typedef big_int32_ut native_int32_ut;
|
||||
typedef big_int40_ut native_int40_ut;
|
||||
typedef big_int48_ut native_int48_ut;
|
||||
typedef big_int56_ut native_int56_ut;
|
||||
typedef big_int64_ut native_int64_ut;
|
||||
typedef endian_arithmetic<order::native, int_least8_t, 8> native_int8_t;
|
||||
typedef endian_arithmetic<order::native, int_least16_t, 16> native_int16_t;
|
||||
typedef endian_arithmetic<order::native, int_least32_t, 24> native_int24_t;
|
||||
typedef endian_arithmetic<order::native, int_least32_t, 32> native_int32_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 40> native_int40_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 48> native_int48_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 56> native_int56_t;
|
||||
typedef endian_arithmetic<order::native, int_least64_t, 64> native_int64_t;
|
||||
|
||||
// native endian unsigned integer unaligned types
|
||||
typedef big_uint8_ut native_uint8_ut;
|
||||
typedef big_uint16_ut native_uint16_ut;
|
||||
typedef big_uint24_ut native_uint24_ut;
|
||||
typedef big_uint32_ut native_uint32_ut;
|
||||
typedef big_uint40_ut native_uint40_ut;
|
||||
typedef big_uint48_ut native_uint48_ut;
|
||||
typedef big_uint56_ut native_uint56_ut;
|
||||
typedef big_uint64_ut native_uint64_ut;
|
||||
typedef endian_arithmetic<order::native, uint_least8_t, 8> native_uint8_t;
|
||||
typedef endian_arithmetic<order::native, uint_least16_t, 16> native_uint16_t;
|
||||
typedef endian_arithmetic<order::native, uint_least32_t, 24> native_uint24_t;
|
||||
typedef endian_arithmetic<order::native, uint_least32_t, 32> native_uint32_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 40> native_uint40_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 48> native_uint48_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 56> native_uint56_t;
|
||||
typedef endian_arithmetic<order::native, uint_least64_t, 64> native_uint64_t;
|
||||
|
||||
// native endian floating point types
|
||||
typedef big_float32_ut native_float32_ut;
|
||||
typedef big_float64_ut native_float64_ut;
|
||||
typedef big_float32_t native_float32_t;
|
||||
typedef big_float64_t native_float64_t;
|
||||
# else
|
||||
// native endian signed integer unaligned types
|
||||
typedef little_int8_ut native_int8_ut;
|
||||
typedef little_int16_ut native_int16_ut;
|
||||
typedef little_int24_ut native_int24_ut;
|
||||
typedef little_int32_ut native_int32_ut;
|
||||
typedef little_int40_ut native_int40_ut;
|
||||
typedef little_int48_ut native_int48_ut;
|
||||
typedef little_int56_ut native_int56_ut;
|
||||
typedef little_int64_ut native_int64_ut;
|
||||
|
||||
// native endian unsigned integer unaligned types
|
||||
typedef little_uint8_ut native_uint8_ut;
|
||||
typedef little_uint16_ut native_uint16_ut;
|
||||
typedef little_uint24_ut native_uint24_ut;
|
||||
typedef little_uint32_ut native_uint32_ut;
|
||||
typedef little_uint40_ut native_uint40_ut;
|
||||
typedef little_uint48_ut native_uint48_ut;
|
||||
typedef little_uint56_ut native_uint56_ut;
|
||||
typedef little_uint64_ut native_uint64_ut;
|
||||
|
||||
// native endian floating point types
|
||||
typedef little_float32_ut native_float32_ut;
|
||||
typedef little_float64_ut native_float64_ut;
|
||||
typedef little_float32_t native_float32_t;
|
||||
typedef little_float64_t native_float64_t;
|
||||
# endif
|
||||
} // namespace boost
|
||||
} // namespace endian
|
||||
// unaligned floating point types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::no> big_float32_t;
|
||||
typedef endian_arithmetic<order::big, double, 64, align::no> big_float64_t;
|
||||
typedef endian_arithmetic<order::little, float, 32, align::no> little_float32_t;
|
||||
typedef endian_arithmetic<order::little, double, 64, align::no> little_float64_t;
|
||||
typedef endian_arithmetic<order::native, float, 32, align::no> native_float32_t;
|
||||
typedef endian_arithmetic<order::native, double, 64, align::no> native_float64_t;
|
||||
|
||||
//---------------------------------- end synopsis ------------------------------------//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(align) Align>
|
||||
class endian_arithmetic
|
||||
{
|
||||
private:
|
||||
|
||||
// endian class template specializations ---------------------------------------------//
|
||||
typedef endian_buffer<Order, T, n_bits, Align> buffer_type;
|
||||
|
||||
// Specializations that represent unaligned bytes.
|
||||
// Taking an integer type as a parameter provides a nice way to pass both
|
||||
// the size and signness of the desired integer and get the appropriate
|
||||
// corresponding integer type for the interface.
|
||||
#ifdef BOOST_ENDIAN_NO_CTORS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
|
||||
// unaligned integer big endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_arithmetic< order::big, T, n_bits, align::no >
|
||||
: public endian_buffer< order::big, T, n_bits, align::no >,
|
||||
cover_operators<endian_arithmetic<order::big, T, n_bits>, T>
|
||||
buffer_type buf_;
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
#ifndef BOOST_ENDIAN_NO_CTORS
|
||||
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic( T val ) BOOST_NOEXCEPT: buf_( val )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_big_endian<T, n_bits/8>(this->m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
|
||||
// unaligned float big endian specialization
|
||||
template <>
|
||||
class endian_arithmetic< order::big, float, 32, align::no >
|
||||
: public endian_buffer< order::big, float, 32, align::no >,
|
||||
cover_operators< endian_arithmetic< order::big, float, 32 >, float >
|
||||
{
|
||||
public:
|
||||
typedef float value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, this->m_value); }
|
||||
# endif
|
||||
endian_arithmetic& operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, this->m_value); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
}
|
||||
|
||||
// unaligned double big endian specialization
|
||||
template <>
|
||||
class endian_arithmetic< order::big, double, 64, align::no >
|
||||
: public endian_buffer< order::big, double, 64, align::no >,
|
||||
cover_operators< endian_arithmetic< order::big, double, 64 >, double >
|
||||
{
|
||||
public:
|
||||
typedef double value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, this->m_value); }
|
||||
# endif
|
||||
endian_arithmetic& operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, this->m_value); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
|
||||
// unaligned float little endian specialization
|
||||
template <>
|
||||
class endian_arithmetic< order::little, float, 32, align::no >
|
||||
: public endian_buffer< order::little, float, 32, align::no >,
|
||||
cover_operators< endian_arithmetic< order::little, float, 32 >, float >
|
||||
{
|
||||
public:
|
||||
typedef float value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, this->m_value); }
|
||||
# endif
|
||||
endian_arithmetic& operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, this->m_value); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
// unaligned double little endian specialization
|
||||
template <>
|
||||
class endian_arithmetic< order::little, double, 64, align::no >
|
||||
: public endian_buffer< order::little, double, 64, align::no >,
|
||||
cover_operators< endian_arithmetic< order::little, double, 64 >, double >
|
||||
endian_arithmetic& operator=( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
public:
|
||||
typedef double value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, this->m_value); }
|
||||
# endif
|
||||
endian_arithmetic& operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, this->m_value); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
buf_ = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// unaligned little endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_arithmetic< order::little, T, n_bits, align::no >
|
||||
: public endian_buffer< order::little, T, n_bits, align::no >,
|
||||
cover_operators< endian_arithmetic< order::little, T, n_bits >, T >
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_little_endian<T, n_bits/8>(this->m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; }
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
return buf_.value();
|
||||
}
|
||||
|
||||
// align::yes specializations; only n_bits == 16/32/64 supported
|
||||
|
||||
// aligned big endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_arithmetic<order::big, T, n_bits, align::yes>
|
||||
: public endian_buffer< order::big, T, n_bits, align::yes >,
|
||||
cover_operators<endian_arithmetic<order::big, T, n_bits, align::yes>, T>
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
|
||||
return buf_.data();
|
||||
}
|
||||
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
return buf_.data();
|
||||
}
|
||||
|
||||
operator value_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
operator buffer_type& () BOOST_NOEXCEPT
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
operator buffer_type const& () BOOST_NOEXCEPT
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
// operators
|
||||
|
||||
T operator+() const BOOST_NOEXCEPT
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
endian_arithmetic& operator+=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() + y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator-=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() - y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator*=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() * y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator/=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() / y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator%=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() % y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator&=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() & y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator|=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() | y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator^=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() ^ y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator<<=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() << y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator>>=( T y ) BOOST_NOEXCEPT
|
||||
{
|
||||
*this = static_cast<T>( this->value() >> y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator++() BOOST_NOEXCEPT
|
||||
{
|
||||
*this += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic& operator--() BOOST_NOEXCEPT
|
||||
{
|
||||
*this -= 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
endian_arithmetic operator++(int) BOOST_NOEXCEPT
|
||||
{
|
||||
endian_arithmetic tmp( *this );
|
||||
*this += 1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
endian_arithmetic operator--(int) BOOST_NOEXCEPT
|
||||
{
|
||||
endian_arithmetic tmp( *this );
|
||||
*this -= 1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<class Ch, class Tr>
|
||||
friend std::basic_ostream<Ch, Tr>&
|
||||
operator<<( std::basic_ostream<Ch, Tr>& os, endian_arithmetic const& x )
|
||||
{
|
||||
return os << x.value();
|
||||
}
|
||||
|
||||
template<class Ch, class Tr>
|
||||
friend std::basic_istream<Ch, Tr>&
|
||||
operator>>( std::basic_istream<Ch, Tr>& is, endian_arithmetic& x )
|
||||
{
|
||||
T i;
|
||||
|
||||
if( is >> i )
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
this->m_value = ::boost::endian::native_to_big(val);
|
||||
x = i;
|
||||
}
|
||||
|
||||
# endif
|
||||
endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
this->m_value = ::boost::endian::native_to_big(val);
|
||||
return *this;
|
||||
}
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
|
||||
// aligned little endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_arithmetic<order::little, T, n_bits, align::yes>
|
||||
: public endian_buffer< order::little, T, n_bits, align::yes >,
|
||||
cover_operators<endian_arithmetic<order::little, T, n_bits, align::yes>, T>
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
this->m_value = ::boost::endian::native_to_little(val);
|
||||
}
|
||||
# endif
|
||||
endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
this->m_value = ::boost::endian::native_to_little(val);
|
||||
return *this;
|
||||
}
|
||||
operator value_type() const BOOST_NOEXCEPT { return this->value(); }
|
||||
};
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ENDIAN_HPP
|
||||
#endif // BOOST_ENDIAN_ARITHMETIC_HPP
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
// (C) Copyright Darin Adler 2000
|
||||
// (C) Copyright Beman Dawes 2006, 2009, 2014
|
||||
// (C) Copyright Peter Dimov 2019
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
@ -21,28 +22,25 @@
|
||||
#ifndef BOOST_ENDIAN_BUFFERS_HPP
|
||||
#define BOOST_ENDIAN_BUFFERS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_ENDIAN_LOG
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef/detail/endian_compat.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/endian/detail/endian_store.hpp>
|
||||
#include <boost/endian/detail/endian_load.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/detail/scoped_enum_emulation.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <iosfwd>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
# if CHAR_BIT != 8
|
||||
# error Platforms with CHAR_BIT != 8 are not supported
|
||||
@ -54,7 +52,8 @@
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
// g++ pre-4.6 does not support unrestricted unions, but we have no Config macro for that
|
||||
# if (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || BOOST_WORKAROUND(BOOST_GCC, < 40600)) && defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
# define BOOST_ENDIAN_NO_CTORS
|
||||
# endif
|
||||
|
||||
@ -65,540 +64,317 @@ namespace boost
|
||||
namespace endian
|
||||
{
|
||||
|
||||
#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
BOOST_SCOPED_ENUM_START(order)
|
||||
{
|
||||
big, little,
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
native = big
|
||||
# else
|
||||
native = little
|
||||
# endif
|
||||
BOOST_SCOPED_ENUM_START(align)
|
||||
{no, yes
|
||||
# ifdef BOOST_ENDIAN_DEPRECATED_NAMES
|
||||
, unaligned = no, aligned = yes
|
||||
# endif
|
||||
}; BOOST_SCOPED_ENUM_END
|
||||
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
#endif
|
||||
BOOST_SCOPED_ENUM_START(align) {no, yes}; BOOST_SCOPED_ENUM_END
|
||||
|
||||
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(align) A = align::no>
|
||||
class endian_buffer;
|
||||
|
||||
// aligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_t;
|
||||
typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_t;
|
||||
|
||||
// aligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_t;
|
||||
typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_t;
|
||||
|
||||
// unaligned big endian floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_ut;
|
||||
typedef endian_buffer<order::big, double, 64, align::no> big_float64_buf_ut;
|
||||
|
||||
// unaligned little endian floating point buffers
|
||||
typedef endian_buffer<order::little, float, 32, align::no> little_float32_buf_ut;
|
||||
typedef endian_buffer<order::little, double, 64, align::no> little_float64_buf_ut;
|
||||
|
||||
// aligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_t;
|
||||
typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_t;
|
||||
typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_t;
|
||||
typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
|
||||
typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
|
||||
typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
|
||||
typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;
|
||||
|
||||
// aligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_t;
|
||||
typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_t;
|
||||
typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_t;
|
||||
typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
|
||||
typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
|
||||
typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
|
||||
typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;
|
||||
|
||||
// aligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_t;
|
||||
typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_t;
|
||||
typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_t;
|
||||
typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
|
||||
typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at;
|
||||
typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at;
|
||||
typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at;
|
||||
|
||||
// aligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_t;
|
||||
typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_t;
|
||||
typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_t;
|
||||
typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at;
|
||||
typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;
|
||||
typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;
|
||||
typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;
|
||||
|
||||
// aligned floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_at;
|
||||
typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_at;
|
||||
typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_at;
|
||||
typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_at;
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
// unaligned big endian signed integer buffers
|
||||
typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_ut;
|
||||
typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
|
||||
typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
|
||||
typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
|
||||
typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
|
||||
typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;
|
||||
|
||||
// unaligned big endian unsigned integer buffers
|
||||
typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_ut;
|
||||
typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
|
||||
typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;
|
||||
|
||||
// unaligned little endian signed integer buffers
|
||||
typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_ut;
|
||||
typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
|
||||
typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
|
||||
typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
|
||||
typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
|
||||
typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;
|
||||
|
||||
// unaligned little endian unsigned integer buffers
|
||||
typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_ut;
|
||||
typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
|
||||
typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;
|
||||
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
// unaligned native endian signed integer buffers
|
||||
typedef big_int8_buf_ut native_int8_buf_ut;
|
||||
typedef big_int16_buf_ut native_int16_buf_ut;
|
||||
typedef big_int24_buf_ut native_int24_buf_ut;
|
||||
typedef big_int32_buf_ut native_int32_buf_ut;
|
||||
typedef big_int40_buf_ut native_int40_buf_ut;
|
||||
typedef big_int48_buf_ut native_int48_buf_ut;
|
||||
typedef big_int56_buf_ut native_int56_buf_ut;
|
||||
typedef big_int64_buf_ut native_int64_buf_ut;
|
||||
typedef endian_buffer<order::native, int_least8_t, 8> native_int8_buf_t;
|
||||
typedef endian_buffer<order::native, int_least16_t, 16> native_int16_buf_t;
|
||||
typedef endian_buffer<order::native, int_least32_t, 24> native_int24_buf_t;
|
||||
typedef endian_buffer<order::native, int_least32_t, 32> native_int32_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 40> native_int40_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 48> native_int48_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 56> native_int56_buf_t;
|
||||
typedef endian_buffer<order::native, int_least64_t, 64> native_int64_buf_t;
|
||||
|
||||
// unaligned native endian unsigned integer buffers
|
||||
typedef big_uint8_buf_ut native_uint8_buf_ut;
|
||||
typedef big_uint16_buf_ut native_uint16_buf_ut;
|
||||
typedef big_uint24_buf_ut native_uint24_buf_ut;
|
||||
typedef big_uint32_buf_ut native_uint32_buf_ut;
|
||||
typedef big_uint40_buf_ut native_uint40_buf_ut;
|
||||
typedef big_uint48_buf_ut native_uint48_buf_ut;
|
||||
typedef big_uint56_buf_ut native_uint56_buf_ut;
|
||||
typedef big_uint64_buf_ut native_uint64_buf_ut;
|
||||
typedef endian_buffer<order::native, uint_least8_t, 8> native_uint8_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least16_t, 16> native_uint16_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least32_t, 24> native_uint24_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least32_t, 32> native_uint32_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 40> native_uint40_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 48> native_uint48_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 56> native_uint56_buf_t;
|
||||
typedef endian_buffer<order::native, uint_least64_t, 64> native_uint64_buf_t;
|
||||
|
||||
// native endian floating point buffers
|
||||
typedef big_float32_buf_ut native_float32_buf_ut;
|
||||
typedef big_float64_buf_ut native_float64_buf_ut;
|
||||
typedef big_float32_buf_t native_float32_buf_t;
|
||||
typedef big_float64_buf_t native_float64_buf_t;
|
||||
# else
|
||||
// unaligned native endian signed integer buffers
|
||||
typedef little_int8_buf_ut native_int8_buf_ut;
|
||||
typedef little_int16_buf_ut native_int16_buf_ut;
|
||||
typedef little_int24_buf_ut native_int24_buf_ut;
|
||||
typedef little_int32_buf_ut native_int32_buf_ut;
|
||||
typedef little_int40_buf_ut native_int40_buf_ut;
|
||||
typedef little_int48_buf_ut native_int48_buf_ut;
|
||||
typedef little_int56_buf_ut native_int56_buf_ut;
|
||||
typedef little_int64_buf_ut native_int64_buf_ut;
|
||||
// unaligned floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_t;
|
||||
typedef endian_buffer<order::big, double, 64, align::no> big_float64_buf_t;
|
||||
typedef endian_buffer<order::little, float, 32, align::no> little_float32_buf_t;
|
||||
typedef endian_buffer<order::little, double, 64, align::no> little_float64_buf_t;
|
||||
typedef endian_buffer<order::native, float, 32, align::no> native_float32_buf_t;
|
||||
typedef endian_buffer<order::native, double, 64, align::no> native_float64_buf_t;
|
||||
|
||||
// unaligned native endian unsigned integer buffers
|
||||
typedef little_uint8_buf_ut native_uint8_buf_ut;
|
||||
typedef little_uint16_buf_ut native_uint16_buf_ut;
|
||||
typedef little_uint24_buf_ut native_uint24_buf_ut;
|
||||
typedef little_uint32_buf_ut native_uint32_buf_ut;
|
||||
typedef little_uint40_buf_ut native_uint40_buf_ut;
|
||||
typedef little_uint48_buf_ut native_uint48_buf_ut;
|
||||
typedef little_uint56_buf_ut native_uint56_buf_ut;
|
||||
typedef little_uint64_buf_ut native_uint64_buf_ut;
|
||||
// Stream inserter
|
||||
template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
|
||||
std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
|
||||
std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os,
|
||||
const endian_buffer<Order, T, n_bits, A>& x)
|
||||
{
|
||||
return os << x.value();
|
||||
}
|
||||
|
||||
// native endian floating point buffers
|
||||
typedef little_float32_buf_ut native_float32_buf_ut;
|
||||
typedef little_float64_buf_ut native_float64_buf_ut;
|
||||
typedef little_float32_buf_t native_float32_buf_t;
|
||||
typedef little_float64_buf_t native_float64_buf_t;
|
||||
# endif
|
||||
} // namespace boost
|
||||
} // namespace endian
|
||||
// Stream extractor
|
||||
template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
|
||||
std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
|
||||
std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is,
|
||||
endian_buffer<Order, T, n_bits, A>& x)
|
||||
{
|
||||
T i;
|
||||
if (is >> i)
|
||||
x = i;
|
||||
return is;
|
||||
}
|
||||
|
||||
//---------------------------------- end synopsis ------------------------------------//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Unrolled loops for loading and storing streams of bytes.
|
||||
|
||||
template <typename T, std::size_t n_bytes,
|
||||
bool sign=boost::is_signed<T>::value >
|
||||
struct unrolled_byte_loops
|
||||
{
|
||||
typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
|
||||
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); }
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); }
|
||||
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
*(bytes - 1) = static_cast<char>(value);
|
||||
next::store_big(bytes - 1, static_cast<T>(value >> 8));
|
||||
}
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
*bytes = static_cast<char>(value);
|
||||
next::store_little(bytes + 1, static_cast<T>(value >> 8));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, false>
|
||||
{
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *(bytes - 1); }
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *bytes; }
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, true>
|
||||
{
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *reinterpret_cast<const signed char*>(bytes - 1); }
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *reinterpret_cast<const signed char*>(bytes); }
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
};
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_big_endian(const void* bytes) BOOST_NOEXCEPT
|
||||
{
|
||||
return unrolled_byte_loops<T, n_bytes>::load_big
|
||||
(static_cast<const unsigned char*>(bytes) + n_bytes);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_little_endian(const void* bytes) BOOST_NOEXCEPT
|
||||
{
|
||||
return unrolled_byte_loops<T, n_bytes>::load_little
|
||||
(static_cast<const unsigned char*>(bytes));
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_big
|
||||
(static_cast<char*>(bytes) + n_bytes, value);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_little
|
||||
(static_cast<char*>(bytes), value);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
bool endian_log(true);
|
||||
# endif
|
||||
|
||||
// endian_buffer class template specializations --------------------------------------//
|
||||
|
||||
// Specializations that represent unaligned bytes.
|
||||
// Taking an integer type as a parameter provides a nice way to pass both
|
||||
// the size and signedness of the desired integer and get the appropriate
|
||||
// corresponding integer type for the interface.
|
||||
// Specializations that represent unaligned bytes.
|
||||
// Taking an integer type as a parameter provides a nice way to pass both
|
||||
// the size and signedness of the desired integer and get the appropriate
|
||||
// corresponding integer type for the interface.
|
||||
|
||||
// Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?
|
||||
// A: No. The rationale for endian_buffers is to prevent high-cost hidden
|
||||
// conversions. If an implicit conversion operator is supplied, hidden conversions
|
||||
// can occur.
|
||||
// Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?
|
||||
// A: No. The rationale for endian_buffers is to prevent high-cost hidden
|
||||
// conversions. If an implicit conversion operator is supplied, hidden conversions
|
||||
// can occur.
|
||||
|
||||
// unaligned big endian_buffer specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_buffer< order::big, T, n_bits, align::no >
|
||||
// unaligned endian_buffer specialization
|
||||
|
||||
template< BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits >
|
||||
class endian_buffer<Order, T, n_bits, align::no>
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_CTORS
|
||||
public:
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
|
||||
unsigned char value_[ n_bits / 8 ];
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
#ifndef BOOST_ENDIAN_NO_CTORS
|
||||
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
|
||||
explicit endian_buffer( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, unaligned, "
|
||||
<< n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_big_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian_buffer & operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if (endian_log)
|
||||
std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_big_endian<T, n_bits/8>(m_value, val);
|
||||
return *this;
|
||||
}
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, unaligned, " << n_bits << "-bits, convert("
|
||||
<< detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
|
||||
# endif
|
||||
return detail::load_big_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
|
||||
// unaligned float big endian_buffer specialization
|
||||
template <>
|
||||
class endian_buffer< order::big, float, 32, align::no >
|
||||
boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
endian_buffer& operator=( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
public:
|
||||
typedef float value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, m_value); }
|
||||
# endif
|
||||
endian_buffer & operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, m_value); return *this; }
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
value_type tmp;
|
||||
detail::big_reverse_copy(m_value, tmp);
|
||||
return tmp;
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[sizeof(value_type)];
|
||||
boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );
|
||||
}
|
||||
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
// aligned specializations; only n_bits == 16/32/64 supported
|
||||
|
||||
// aligned endian_buffer specialization
|
||||
|
||||
template< BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits >
|
||||
class endian_buffer<Order, T, n_bits, align::yes>
|
||||
{
|
||||
private:
|
||||
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
|
||||
union
|
||||
{
|
||||
unsigned char value_[ n_bits / 8 ];
|
||||
T align_;
|
||||
};
|
||||
|
||||
// unaligned double big endian_buffer specialization
|
||||
template <>
|
||||
class endian_buffer< order::big, double, 64, align::no >
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
#ifndef BOOST_ENDIAN_NO_CTORS
|
||||
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
|
||||
explicit endian_buffer( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
public:
|
||||
typedef double value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, m_value); }
|
||||
# endif
|
||||
endian_buffer & operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::big_reverse_copy(val, m_value); return *this; }
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
value_type tmp;
|
||||
detail::big_reverse_copy(m_value, tmp);
|
||||
return tmp;
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[sizeof(value_type)];
|
||||
};
|
||||
|
||||
// unaligned float little endian_buffer specialization
|
||||
template <>
|
||||
class endian_buffer< order::little, float, 32, align::no >
|
||||
boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
endian_buffer& operator=( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
public:
|
||||
typedef float value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, m_value); }
|
||||
# endif
|
||||
endian_buffer & operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, m_value); return *this; }
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
value_type tmp;
|
||||
detail::little_reverse_copy(m_value, tmp);
|
||||
return tmp;
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[sizeof(value_type)];
|
||||
};
|
||||
boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );
|
||||
return *this;
|
||||
}
|
||||
|
||||
// unaligned double little endian_buffer specialization
|
||||
template <>
|
||||
class endian_buffer< order::little, double, 64, align::no >
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
public:
|
||||
typedef double value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, m_value); }
|
||||
# endif
|
||||
endian_buffer & operator=(value_type val) BOOST_NOEXCEPT
|
||||
{ detail::little_reverse_copy(val, m_value); return *this; }
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
value_type tmp;
|
||||
detail::little_reverse_copy(m_value, tmp);
|
||||
return tmp;
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[sizeof(value_type)];
|
||||
};
|
||||
return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );
|
||||
}
|
||||
|
||||
// unaligned little endian_buffer specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_buffer< order::little, T, n_bits, align::no >
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, unaligned, " << n_bits << "-bits, construct("
|
||||
<< val << ")\n";
|
||||
# endif
|
||||
detail::store_little_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian_buffer & operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, unaligned, " << n_bits << "-bits, convert("
|
||||
<< detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
|
||||
# endif
|
||||
return detail::load_little_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
protected:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
return value_;
|
||||
}
|
||||
|
||||
// align::yes specializations; only n_bits == 16/32/64 supported
|
||||
|
||||
// aligned big endian_buffer specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_buffer<order::big, T, n_bits, align::yes>
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, aligned, " << n_bits
|
||||
<< "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
m_value = ::boost::endian::native_to_big(val);
|
||||
}
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
# endif
|
||||
endian_buffer& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
m_value = ::boost::endian::native_to_big(val);
|
||||
return *this;
|
||||
}
|
||||
//operator value_type() const BOOST_NOEXCEPT
|
||||
//{
|
||||
// return ::boost::endian::big_to_native(m_value);
|
||||
//}
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "big, aligned, " << n_bits << "-bits, convert("
|
||||
<< ::boost::endian::big_to_native(m_value) << ")\n";
|
||||
# endif
|
||||
return ::boost::endian::big_to_native(m_value);
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT
|
||||
{return reinterpret_cast<const char*>(&m_value);}
|
||||
protected:
|
||||
T m_value;
|
||||
};
|
||||
// aligned native endian_buffer specialization
|
||||
|
||||
// aligned little endian_buffer specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian_buffer<order::little, T, n_bits, align::yes>
|
||||
template< class T, std::size_t n_bits >
|
||||
class endian_buffer<order::native, T, n_bits, align::yes>
|
||||
{
|
||||
private:
|
||||
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
|
||||
T value_;
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
#ifndef BOOST_ENDIAN_NO_CTORS
|
||||
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
|
||||
explicit endian_buffer( T val ) BOOST_NOEXCEPT: value_( val )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian_buffer(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, aligned, " << n_bits
|
||||
<< "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
m_value = ::boost::endian::native_to_little(val);
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
endian_buffer& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
m_value = ::boost::endian::native_to_little(val);
|
||||
return *this;
|
||||
}
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::cout << "little, aligned, " << n_bits << "-bits, convert("
|
||||
<< ::boost::endian::little_to_native(m_value) << ")\n";
|
||||
# endif
|
||||
return ::boost::endian::little_to_native(m_value);
|
||||
}
|
||||
const char* data() const BOOST_NOEXCEPT
|
||||
{return reinterpret_cast<const char*>(&m_value);}
|
||||
protected:
|
||||
T m_value;
|
||||
};
|
||||
#endif
|
||||
|
||||
endian_buffer& operator=( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
value_ = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast< unsigned char const* >( &value_ );
|
||||
}
|
||||
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast< unsigned char* >( &value_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ENDIAN_BUFFERS_HPP
|
||||
|
@ -5,17 +5,19 @@
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_ENDIAN_CONVERTERS_HPP
|
||||
#define BOOST_ENDIAN_CONVERTERS_HPP
|
||||
#ifndef BOOST_ENDIAN_CONVERSION_HPP
|
||||
#define BOOST_ENDIAN_CONVERSION_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef/detail/endian_compat.h>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/endian/detail/intrinsic.hpp>
|
||||
#include <boost/detail/scoped_enum_emulation.hpp>
|
||||
#include <boost/endian/detail/endian_reverse.hpp>
|
||||
#include <boost/endian/detail/endian_load.hpp>
|
||||
#include <boost/endian/detail/endian_store.hpp>
|
||||
#include <boost/endian/detail/order.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring> // for memcpy
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//------------------------------------- synopsis ---------------------------------------//
|
||||
|
||||
@ -23,18 +25,6 @@ namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
BOOST_SCOPED_ENUM_START(order)
|
||||
{
|
||||
big, little,
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
native = big
|
||||
# else
|
||||
native = little
|
||||
# endif
|
||||
}; BOOST_SCOPED_ENUM_END
|
||||
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// //
|
||||
@ -51,40 +41,33 @@ namespace endian
|
||||
// by argument dependent lookup (ADL). //
|
||||
// //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// customization for built-in arithmetic types
|
||||
inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT;
|
||||
inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT;
|
||||
inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT;
|
||||
inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT;
|
||||
inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT;
|
||||
inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT;
|
||||
inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT;
|
||||
inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT;
|
||||
// TODO: Track progress of Floating-Point Typedefs Having Specified Widths proposal (N3626)
|
||||
inline float endian_reverse(float x) BOOST_NOEXCEPT;
|
||||
inline double endian_reverse(double x) BOOST_NOEXCEPT;
|
||||
|
||||
// reverse byte order
|
||||
// requires T to be a non-bool integral type
|
||||
// in detail/endian_reverse.hpp
|
||||
//
|
||||
// template<class T> inline BOOST_CONSTEXPR T endian_reverse( T x ) BOOST_NOEXCEPT;
|
||||
|
||||
// reverse byte order unless native endianness is big
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
|
||||
inline BOOST_CONSTEXPR EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
|
||||
// Returns: x if native endian order is big, otherwise endian_reverse(x)
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
|
||||
// Returns: x if native endian order is big, otherwise endian_reverse(x)
|
||||
|
||||
// reverse byte order unless native endianness is little
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
|
||||
inline BOOST_CONSTEXPR EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
|
||||
// Returns: x if native endian order is little, otherwise endian_reverse(x)
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
|
||||
// Returns: x if native endian order is little, otherwise endian_reverse(x)
|
||||
|
||||
// generic conditional reverse byte order
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversible>
|
||||
inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
|
||||
// Returns: If From == To have different values, from.
|
||||
// Otherwise endian_reverse(from).
|
||||
// Remarks: The From == To test, and as a consequence which form the return takes, is
|
||||
@ -92,7 +75,7 @@ namespace endian
|
||||
|
||||
// runtime conditional reverse byte order
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible conditional_reverse(EndianReversible from,
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from,
|
||||
BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
|
||||
BOOST_NOEXCEPT;
|
||||
// Returns: from_order == to_order ? from : endian_reverse(from).
|
||||
@ -100,7 +83,7 @@ namespace endian
|
||||
//------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
// Q: What happended to bswap, htobe, and the other synonym functions based on names
|
||||
// Q: What happened to bswap, htobe, and the other synonym functions based on names
|
||||
// popularized by BSD, OS X, and Linux?
|
||||
// A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
|
||||
// for such functionality. Since macros would cause endless problems with functions
|
||||
@ -114,7 +97,7 @@ namespace endian
|
||||
// //
|
||||
// user-defined types (UDTs) //
|
||||
// //
|
||||
// All reverse in place function templates are required to be implemented in terms //
|
||||
// All reverse in place function templates are required to be implemented in terms //
|
||||
// of an unqualified call to "endian_reverse_inplace(x)", a function reversing //
|
||||
// the endianness of x, which is a non-const reference. This provides a //
|
||||
// customization point for any UDT that provides a "reverse_inplace" free-function //
|
||||
@ -125,9 +108,12 @@ namespace endian
|
||||
//------------------------------------------------------------------------------------//
|
||||
|
||||
// reverse in place
|
||||
template <class EndianReversible>
|
||||
inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
|
||||
// Effects: x = endian_reverse(x)
|
||||
// in detail/endian_reverse.hpp
|
||||
//
|
||||
// template <class EndianReversible>
|
||||
// inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
|
||||
//
|
||||
// Effects: x = endian_reverse(x)
|
||||
|
||||
// reverse in place unless native endianness is big
|
||||
template <class EndianReversibleInplace>
|
||||
@ -148,7 +134,7 @@ namespace endian
|
||||
// generic conditional reverse in place
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
|
||||
inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
|
||||
|
||||
// runtime reverse in place
|
||||
template <class EndianReversibleInplace>
|
||||
@ -158,351 +144,447 @@ namespace endian
|
||||
|
||||
//----------------------------------- end synopsis -------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// generic reverse function template implementation approach using std::reverse
|
||||
// suggested by Mathias Gaunard. Primary motivation for inclusion is to have an
|
||||
// independent implementation to test against. Secondary motivation is use by
|
||||
// floating-point endian_reverse, but that use is likely to be replace by a
|
||||
// more tailored floating-point implementation.
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible big_to_native( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::conditional_reverse<order::big, order::native>( x );
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T std_endian_reverse(T x) BOOST_NOEXCEPT
|
||||
{
|
||||
T tmp(x);
|
||||
std::reverse(
|
||||
reinterpret_cast<char*>(&tmp),
|
||||
reinterpret_cast<char*>(&tmp) + sizeof(T));
|
||||
return tmp;
|
||||
}
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_big( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::conditional_reverse<order::native, order::big>( x );
|
||||
}
|
||||
|
||||
// conditional unaligned reverse copy, patterned after std::reverse_copy
|
||||
template <class T>
|
||||
inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
|
||||
template <class T>
|
||||
inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
|
||||
template <class T>
|
||||
inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
|
||||
template <class T>
|
||||
inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
|
||||
} // namespace detail
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible little_to_native( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::conditional_reverse<order::little, order::native>( x );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// //
|
||||
// return-by-value implementation //
|
||||
// //
|
||||
// -- portable approach suggested by tymofey, with avoidance of undefined behavior //
|
||||
// as suggested by Giovanni Piero Deretta, with a further refinement suggested //
|
||||
// by Pyry Jahkola. //
|
||||
// -- intrinsic approach suggested by reviewers, and by David Stone, who provided //
|
||||
// his Boost licensed macro implementation (detail/intrinsic.hpp) //
|
||||
// //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_little( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::conditional_reverse<order::native, order::little>( x );
|
||||
}
|
||||
|
||||
inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::true_type ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
return (static_cast<uint16_t>(x) << 8)
|
||||
| (static_cast<uint16_t>(x) >> 8);
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x));
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
uint32_t step16;
|
||||
step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16;
|
||||
return
|
||||
((static_cast<uint32_t>(step16) << 8) & 0xff00ff00)
|
||||
| ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff);
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x));
|
||||
# endif
|
||||
}
|
||||
template<class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::false_type ) BOOST_NOEXCEPT
|
||||
{
|
||||
return endian_reverse( x );
|
||||
}
|
||||
|
||||
inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
uint64_t step32, step16;
|
||||
step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32;
|
||||
step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
|
||||
| (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8
|
||||
| (step16 & 0xFF00FF00FF00FF00ULL) >> 8);
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x));
|
||||
# endif
|
||||
}
|
||||
|
||||
inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
return (x << 8)
|
||||
| (x >> 8);
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x);
|
||||
# endif
|
||||
}
|
||||
// generic conditional reverse
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
|
||||
return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
|
||||
}
|
||||
|
||||
inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
uint32_t step16;
|
||||
step16 = x << 16 | x >> 16;
|
||||
return
|
||||
((step16 << 8) & 0xff00ff00)
|
||||
| ((step16 >> 8) & 0x00ff00ff);
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
uint64_t step32, step16;
|
||||
step32 = x << 32 | x >> 32;
|
||||
step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
|
||||
| (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (step16 & 0x00FF00FF00FF00FFULL) << 8
|
||||
| (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
|
||||
# else
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
inline float endian_reverse(float x) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(float) == sizeof(uint32_t),
|
||||
"boost::endian currently supports only sizeof(float) == 4;"
|
||||
" please report static_assert failure to the boost mailing list");
|
||||
return detail::std_endian_reverse(x);
|
||||
}
|
||||
|
||||
inline double endian_reverse(double x) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(double) == sizeof(uint64_t),
|
||||
"boost::endian currently supports only sizeof(double) == 8;"
|
||||
" please report static_assert failure to the boost mailing list");
|
||||
return detail::std_endian_reverse(x);
|
||||
}
|
||||
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
return x;
|
||||
# else
|
||||
return endian_reverse(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
return x;
|
||||
# else
|
||||
return endian_reverse(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
return x;
|
||||
# else
|
||||
return endian_reverse(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
return x;
|
||||
# else
|
||||
return endian_reverse(x);
|
||||
# endif
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Primary template and specializations to support endian_reverse().
|
||||
// See rationale in endian_reverse() below.
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversible>
|
||||
class value_converter ; // primary template
|
||||
template <class T> class value_converter <order::big, order::big, T>
|
||||
{public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
|
||||
template <class T> class value_converter <order::little, order::little, T>
|
||||
{public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
|
||||
template <class T> class value_converter <order::big, order::little, T>
|
||||
{public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
|
||||
template <class T> class value_converter <order::little, order::big, T>
|
||||
{public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
|
||||
}
|
||||
|
||||
// generic conditional reverse
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversible>
|
||||
inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT {
|
||||
// work around lack of function template partial specialization by instantiating
|
||||
// a function object of a class that is partially specialized on the two order
|
||||
// template parameters, and then calling its operator().
|
||||
detail::value_converter <From, To, EndianReversible> tmp;
|
||||
return tmp(from);
|
||||
}
|
||||
|
||||
// runtime conditional reverse
|
||||
template <class EndianReversible >
|
||||
inline EndianReversible conditional_reverse(EndianReversible from,
|
||||
BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT
|
||||
{
|
||||
return from_order == to_order ? from : endian_reverse(from);
|
||||
}
|
||||
// runtime conditional reverse
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x,
|
||||
BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
|
||||
return from_order == to_order? x: endian_reverse( x );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// reverse-in-place implementation //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// reverse in place
|
||||
template <class EndianReversible>
|
||||
inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT
|
||||
{
|
||||
x = endian_reverse(x);
|
||||
}
|
||||
template <class EndianReversibleInplace>
|
||||
inline void big_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::endian::conditional_reverse_inplace<order::big, order::native>( x );
|
||||
}
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
|
||||
# else
|
||||
inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
|
||||
{ endian_reverse_inplace(x); }
|
||||
# endif
|
||||
template <class EndianReversibleInplace>
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
|
||||
# else
|
||||
inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
|
||||
{
|
||||
endian_reverse_inplace(x);
|
||||
}
|
||||
# endif
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_big_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::endian::conditional_reverse_inplace<order::native, order::big>( x );
|
||||
}
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
|
||||
# else
|
||||
inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
|
||||
{ endian_reverse_inplace(x); }
|
||||
# endif
|
||||
template <class EndianReversibleInplace>
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
|
||||
# else
|
||||
inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
|
||||
{
|
||||
endian_reverse_inplace(x);
|
||||
}
|
||||
# endif
|
||||
template <class EndianReversibleInplace>
|
||||
inline void little_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::endian::conditional_reverse_inplace<order::little, order::native>( x );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Primary template and specializations support generic
|
||||
// endian_reverse_inplace().
|
||||
// See rationale in endian_reverse_inplace() below.
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversibleInplace>
|
||||
class converter; // primary template
|
||||
template <class T> class converter<order::big, order::big, T>
|
||||
{public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
|
||||
template <class T> class converter<order::little, order::little, T>
|
||||
{public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
|
||||
template <class T> class converter<order::big, order::little, T>
|
||||
{public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
|
||||
template <class T> class converter<order::little, order::big, T>
|
||||
{public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
|
||||
} // namespace detail
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_little_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::endian::conditional_reverse_inplace<order::native, order::little>( x );
|
||||
}
|
||||
|
||||
// generic conditional reverse in place
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||
class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
|
||||
{
|
||||
// work around lack of function template partial specialization by instantiating
|
||||
// a function object of a class that is partially specialized on the two order
|
||||
// template parameters, and then calling its operator().
|
||||
detail::converter<From, To, EndianReversibleInplace> tmp;
|
||||
tmp(x); // call operator ()
|
||||
}
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// runtime reverse in place
|
||||
template <class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace(EndianReversibleInplace& x,
|
||||
BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
|
||||
BOOST_NOEXCEPT
|
||||
{
|
||||
if (from_order != to_order)
|
||||
endian_reverse_inplace(x);
|
||||
}
|
||||
template<class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace_impl( EndianReversibleInplace&, boost::true_type ) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
template<class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace_impl( EndianReversibleInplace& x, boost::false_type ) BOOST_NOEXCEPT
|
||||
{
|
||||
endian_reverse_inplace( x );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT
|
||||
} // namespace detail
|
||||
|
||||
// generic conditional reverse in place
|
||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
boost::is_class<EndianReversibleInplace>::value ||
|
||||
boost::is_array<EndianReversibleInplace>::value ||
|
||||
detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
|
||||
detail::conditional_reverse_inplace_impl( x, boost::integral_constant<bool, From == To>() );
|
||||
}
|
||||
|
||||
// runtime reverse in place
|
||||
template <class EndianReversibleInplace>
|
||||
inline void conditional_reverse_inplace( EndianReversibleInplace& x,
|
||||
BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
boost::is_class<EndianReversibleInplace>::value ||
|
||||
boost::is_array<EndianReversibleInplace>::value ||
|
||||
detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
|
||||
if( from_order != to_order )
|
||||
{
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
|
||||
# else
|
||||
std::reverse_copy(reinterpret_cast<const char*>(&from),
|
||||
reinterpret_cast<const char*>(&from) + sizeof(T), to);
|
||||
# endif
|
||||
endian_reverse_inplace( x );
|
||||
}
|
||||
template <class T>
|
||||
inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
|
||||
# else
|
||||
std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
|
||||
# endif
|
||||
}
|
||||
template <class T>
|
||||
inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
|
||||
# else
|
||||
std::reverse_copy(reinterpret_cast<const char*>(&from),
|
||||
reinterpret_cast<const char*>(&from) + sizeof(T), to);
|
||||
# endif
|
||||
}
|
||||
template <class T>
|
||||
inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
|
||||
# else
|
||||
std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
|
||||
# endif
|
||||
}
|
||||
} // namespace detail
|
||||
}
|
||||
|
||||
// load/store convenience functions
|
||||
|
||||
// load 16
|
||||
|
||||
inline boost::int16_t load_little_s16( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int16_t, 2, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint16_t load_little_u16( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint16_t, 2, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int16_t load_big_s16( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int16_t, 2, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint16_t load_big_u16( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint16_t, 2, order::big>( p );
|
||||
}
|
||||
|
||||
// load 24
|
||||
|
||||
inline boost::int32_t load_little_s24( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int32_t, 3, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint32_t load_little_u24( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint32_t, 3, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int32_t load_big_s24( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int32_t, 3, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint32_t load_big_u24( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint32_t, 3, order::big>( p );
|
||||
}
|
||||
|
||||
// load 32
|
||||
|
||||
inline boost::int32_t load_little_s32( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int32_t, 4, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint32_t load_little_u32( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint32_t, 4, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int32_t load_big_s32( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int32_t, 4, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint32_t load_big_u32( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint32_t, 4, order::big>( p );
|
||||
}
|
||||
|
||||
// load 40
|
||||
|
||||
inline boost::int64_t load_little_s40( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 5, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_little_u40( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 5, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int64_t load_big_s40( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 5, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_big_u40( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 5, order::big>( p );
|
||||
}
|
||||
|
||||
// load 48
|
||||
|
||||
inline boost::int64_t load_little_s48( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 6, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_little_u48( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 6, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int64_t load_big_s48( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 6, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_big_u48( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 6, order::big>( p );
|
||||
}
|
||||
|
||||
// load 56
|
||||
|
||||
inline boost::int64_t load_little_s56( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 7, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_little_u56( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 7, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int64_t load_big_s56( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 7, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_big_u56( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 7, order::big>( p );
|
||||
}
|
||||
|
||||
// load 64
|
||||
|
||||
inline boost::int64_t load_little_s64( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 8, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_little_u64( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 8, order::little>( p );
|
||||
}
|
||||
|
||||
inline boost::int64_t load_big_s64( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::int64_t, 8, order::big>( p );
|
||||
}
|
||||
|
||||
inline boost::uint64_t load_big_u64( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::endian::endian_load<boost::uint64_t, 8, order::big>( p );
|
||||
}
|
||||
|
||||
// store 16
|
||||
|
||||
inline void store_little_s16( unsigned char * p, boost::int16_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int16_t, 2, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u16( unsigned char * p, boost::uint16_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint16_t, 2, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s16( unsigned char * p, boost::int16_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int16_t, 2, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u16( unsigned char * p, boost::uint16_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint16_t, 2, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 24
|
||||
|
||||
inline void store_little_s24( unsigned char * p, boost::int32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int32_t, 3, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u24( unsigned char * p, boost::uint32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint32_t, 3, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s24( unsigned char * p, boost::int32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int32_t, 3, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u24( unsigned char * p, boost::uint32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint32_t, 3, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 32
|
||||
|
||||
inline void store_little_s32( unsigned char * p, boost::int32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int32_t, 4, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u32( unsigned char * p, boost::uint32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint32_t, 4, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s32( unsigned char * p, boost::int32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int32_t, 4, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u32( unsigned char * p, boost::uint32_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint32_t, 4, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 40
|
||||
|
||||
inline void store_little_s40( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 5, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u40( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 5, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s40( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 5, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u40( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 5, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 48
|
||||
|
||||
inline void store_little_s48( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 6, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u48( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 6, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s48( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 6, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u48( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 6, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 56
|
||||
|
||||
inline void store_little_s56( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 7, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u56( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 7, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s56( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 7, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u56( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 7, order::big>( p, v );
|
||||
}
|
||||
|
||||
// store 64
|
||||
|
||||
inline void store_little_s64( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 8, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_little_u64( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 8, order::little>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_s64( unsigned char * p, boost::int64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::int64_t, 8, order::big>( p, v );
|
||||
}
|
||||
|
||||
inline void store_big_u64( unsigned char * p, boost::uint64_t v )
|
||||
{
|
||||
boost::endian::endian_store<boost::uint64_t, 8, order::big>( p, v );
|
||||
}
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_CONVERTERS_HPP
|
||||
#endif // BOOST_ENDIAN_CONVERSION_HPP
|
||||
|
@ -1,62 +0,0 @@
|
||||
// boost/endian/detail/config.hpp ----------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2003, 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_ENDIAN_CONFIG_HPP
|
||||
#define BOOST_ENDIAN_CONFIG_HPP
|
||||
|
||||
// This header implements separate compilation features as described in
|
||||
// http://www.boost.org/more/separate_compilation.html
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API
|
||||
|
||||
// throw an exception ----------------------------------------------------------------//
|
||||
//
|
||||
// Exceptions were originally thrown via boost::throw_exception().
|
||||
// As throw_exception() became more complex, it caused user error reporting
|
||||
// to be harder to interpret, since the exception reported became much more complex.
|
||||
// The immediate fix was to throw directly, wrapped in a macro to make any later change
|
||||
// easier.
|
||||
|
||||
#define BOOST_ENDIAN_THROW(EX) throw EX
|
||||
|
||||
// enable dynamic linking -------------------------------------------------------------//
|
||||
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
|
||||
# if defined(BOOST_ENDIAN_SOURCE)
|
||||
# define BOOST_ENDIAN_DECL BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define BOOST_ENDIAN_DECL BOOST_SYMBOL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define BOOST_ENDIAN_DECL
|
||||
#endif
|
||||
|
||||
// enable automatic library variant selection ----------------------------------------//
|
||||
|
||||
#if !defined(BOOST_ENDIAN_SOURCE) && !defined(BOOST_ALL_NO_LIB) \
|
||||
&& !defined(BOOST_ENDIAN_NO_LIB)
|
||||
//
|
||||
// Set the name of our library, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#define BOOST_LIB_NAME boost_endian
|
||||
//
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
//
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
#endif
|
||||
//
|
||||
// And include the header that does the work:
|
||||
//
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif // BOOST_ENDIAN_CONFIG_HPP
|
@ -1,141 +0,0 @@
|
||||
// boost/endian/detail/cover_operators.hpp ----------------------------------//
|
||||
|
||||
// Copyright Darin Adler 2000
|
||||
// Copyright Beman Dawes 2008
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
|
||||
#define BOOST_ENDIAN_COVER_OPERATORS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
# include <boost/operators.hpp>
|
||||
# endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// A class that adds arithmetic operators to an arithmetic cover class
|
||||
//
|
||||
// Uses the curiously recurring template pattern (CRTP).
|
||||
//
|
||||
// If the class being covered has a non-explicit conversion to an integer type
|
||||
// then a smaller number of cover operations are needed. Define the macro
|
||||
// BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this.
|
||||
//
|
||||
// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
template <class D, // D is the CRTP derived type, i.e. the cover class
|
||||
class ArithmeticT>
|
||||
class cover_operators
|
||||
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
: boost::operators<D>
|
||||
# endif
|
||||
{
|
||||
// The other operations take advantage of the type conversion that's
|
||||
// built into unary +.
|
||||
|
||||
// Unary operations.
|
||||
friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
|
||||
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; }
|
||||
friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; }
|
||||
friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
|
||||
|
||||
// The basic ordering operations.
|
||||
friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; }
|
||||
friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
|
||||
# endif
|
||||
|
||||
// The basic arithmetic operations.
|
||||
friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x + y); }
|
||||
friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x - y); }
|
||||
friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x * y); }
|
||||
friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x / y); }
|
||||
friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x % y); }
|
||||
friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x & y); }
|
||||
friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x | y); }
|
||||
friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x ^ y); }
|
||||
friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x << y); }
|
||||
friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return x = static_cast<ArithmeticT>(+x >> y); }
|
||||
|
||||
// A few binary arithmetic operations not covered by operators base class.
|
||||
friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return static_cast<ArithmeticT>(+x << y); }
|
||||
friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT
|
||||
{ return static_cast<ArithmeticT>(+x >> y); }
|
||||
|
||||
// Auto-increment and auto-decrement can be defined in terms of the
|
||||
// arithmetic operations.
|
||||
friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; }
|
||||
friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; }
|
||||
|
||||
# ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
friend D operator++(D& x, int) BOOST_NOEXCEPT
|
||||
{
|
||||
D tmp(x);
|
||||
x += 1;
|
||||
return tmp;
|
||||
}
|
||||
friend D operator--(D& x, int) BOOST_NOEXCEPT
|
||||
{
|
||||
D tmp(x);
|
||||
x -= 1;
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_NO_IO_COVER_OPERATORS
|
||||
|
||||
// Stream inserter
|
||||
template <class charT, class traits>
|
||||
friend std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const D& x)
|
||||
{
|
||||
return os << +x;
|
||||
}
|
||||
|
||||
// Stream extractor
|
||||
template <class charT, class traits>
|
||||
friend std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, D& x)
|
||||
{
|
||||
ArithmeticT i;
|
||||
if (is >> i)
|
||||
x = i;
|
||||
return is;
|
||||
}
|
||||
# endif
|
||||
};
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ENDIAN_COVER_OPERATORS_HPP
|
@ -8,5 +8,5 @@
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
589
include/boost/endian/detail/endian_load.hpp
Normal file
589
include/boost/endian/detail/endian_load.hpp
Normal file
@ -0,0 +1,589 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/detail/endian_reverse.hpp>
|
||||
#include <boost/endian/detail/order.hpp>
|
||||
#include <boost/endian/detail/integral_by_size.hpp>
|
||||
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, BOOST_SCOPED_ENUM(order) O2> struct endian_load_impl
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Requires:
|
||||
//
|
||||
// sizeof(T) must be 1, 2, 4, or 8
|
||||
// 1 <= N <= sizeof(T)
|
||||
// T is TriviallyCopyable
|
||||
// if N < sizeof(T), T is integral or enum
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
||||
inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 );
|
||||
BOOST_STATIC_ASSERT( N >= 1 && N <= sizeof(T) );
|
||||
|
||||
return detail::endian_load_impl<T, sizeof(T), order::native, N, Order>()( p );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// same endianness, same size
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_load_impl<T, N, O, N, O>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
T t;
|
||||
std::memcpy( &t, p, N );
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
// same size, reverse endianness
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(order) O2> struct endian_load_impl<T, N, O1, N, O2>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
typename integral_by_size<N>::type tmp;
|
||||
std::memcpy( &tmp, p, N );
|
||||
|
||||
endian_reverse_inplace( tmp );
|
||||
|
||||
T t;
|
||||
std::memcpy( &t, &tmp, N );
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 1 -> 2
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 2, Order, 1, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 2 ];
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
return boost::endian::endian_load<T, 2, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 2, Order, 1, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 2 ];
|
||||
|
||||
tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
tmp[1] = p[0];
|
||||
|
||||
return boost::endian::endian_load<T, 2, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 1 -> 4
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 1, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 1, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = p[0];
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 2 -> 4
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 2, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[1] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 2, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = p[0];
|
||||
tmp[3] = p[1];
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 3 -> 4
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 3, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
tmp[3] = boost::is_signed<T>::value && ( p[2] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4, Order, 3, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
tmp[1] = p[0];
|
||||
tmp[2] = p[1];
|
||||
tmp[3] = p[2];
|
||||
|
||||
return boost::endian::endian_load<T, 4, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 1 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 1, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 1, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
|
||||
tmp[7] = p[0];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 2 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 2, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[1] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 2, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
|
||||
tmp[6] = p[0];
|
||||
tmp[7] = p[1];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 3 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 3, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[2] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 3, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
tmp[4] = fill;
|
||||
|
||||
tmp[5] = p[0];
|
||||
tmp[6] = p[1];
|
||||
tmp[7] = p[2];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 4 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 4, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[3] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
tmp[3] = p[3];
|
||||
|
||||
tmp[4] = fill;
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 4, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
tmp[3] = fill;
|
||||
|
||||
tmp[4] = p[0];
|
||||
tmp[5] = p[1];
|
||||
tmp[6] = p[2];
|
||||
tmp[7] = p[3];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 5 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 5, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[4] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
tmp[3] = p[3];
|
||||
tmp[4] = p[4];
|
||||
|
||||
tmp[5] = fill;
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 5, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
tmp[2] = fill;
|
||||
|
||||
tmp[3] = p[0];
|
||||
tmp[4] = p[1];
|
||||
tmp[5] = p[2];
|
||||
tmp[6] = p[3];
|
||||
tmp[7] = p[4];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 6 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 6, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[5] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
tmp[3] = p[3];
|
||||
tmp[4] = p[4];
|
||||
tmp[5] = p[5];
|
||||
|
||||
tmp[6] = fill;
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 6, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
tmp[1] = fill;
|
||||
|
||||
tmp[2] = p[0];
|
||||
tmp[3] = p[1];
|
||||
tmp[4] = p[2];
|
||||
tmp[5] = p[3];
|
||||
tmp[6] = p[4];
|
||||
tmp[7] = p[5];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
// expanding load 7 -> 8
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 7, order::little>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[6] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = p[0];
|
||||
tmp[1] = p[1];
|
||||
tmp[2] = p[2];
|
||||
tmp[3] = p[3];
|
||||
tmp[4] = p[4];
|
||||
tmp[5] = p[5];
|
||||
tmp[6] = p[6];
|
||||
|
||||
tmp[7] = fill;
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::little>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8, Order, 7, order::big>
|
||||
{
|
||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||
|
||||
tmp[0] = fill;
|
||||
|
||||
tmp[1] = p[0];
|
||||
tmp[2] = p[1];
|
||||
tmp[3] = p[2];
|
||||
tmp[4] = p[3];
|
||||
tmp[5] = p[4];
|
||||
tmp[6] = p[5];
|
||||
tmp[7] = p[6];
|
||||
|
||||
return boost::endian::endian_load<T, 8, order::big>( tmp );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_ENDIAN_LOAD_HPP_INCLUDED
|
178
include/boost/endian/detail/endian_reverse.hpp
Normal file
178
include/boost/endian/detail/endian_reverse.hpp
Normal file
@ -0,0 +1,178 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/detail/integral_by_size.hpp>
|
||||
#include <boost/endian/detail/intrinsic.hpp>
|
||||
#include <boost/endian/detail/is_scoped_enum.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/enable_if.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(BOOST_ENDIAN_NO_INTRINSICS)
|
||||
# if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
# define BOOST_ENDIAN_CONSTEXPR
|
||||
# else
|
||||
# define BOOST_ENDIAN_CONSTEXPR constexpr
|
||||
# endif
|
||||
#else
|
||||
# if defined(BOOST_ENDIAN_CONSTEXPR_INTRINSICS)
|
||||
# define BOOST_ENDIAN_CONSTEXPR BOOST_CONSTEXPR
|
||||
# else
|
||||
# define BOOST_ENDIAN_CONSTEXPR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// -- portable approach suggested by tymofey, with avoidance of undefined behavior
|
||||
// as suggested by Giovanni Piero Deretta, with a further refinement suggested
|
||||
// by Pyry Jahkola.
|
||||
// -- intrinsic approach suggested by reviewers, and by David Stone, who provided
|
||||
// his Boost licensed macro implementation (detail/intrinsic.hpp)
|
||||
|
||||
inline uint8_t BOOST_CONSTEXPR endian_reverse_impl( uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
inline uint16_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
|
||||
return (x << 8) | (x >> 8);
|
||||
|
||||
#else
|
||||
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
|
||||
uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
|
||||
#else
|
||||
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
|
||||
uint64_t step32 = x << 32 | x >> 32;
|
||||
uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
|
||||
|
||||
#else
|
||||
|
||||
return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x);
|
||||
|
||||
# endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
inline uint128_type BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint128_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return endian_reverse_impl( static_cast<uint64_t>( x >> 64 ) ) |
|
||||
static_cast<uint128_type>( endian_reverse_impl( static_cast<uint64_t>( x ) ) ) << 64;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// is_endian_reversible
|
||||
|
||||
template<class T> struct is_endian_reversible: boost::integral_constant<bool,
|
||||
(boost::is_integral<T>::value && !boost::is_same<T, bool>::value) || is_scoped_enum<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
// is_endian_reversible_inplace
|
||||
|
||||
template<class T> struct is_endian_reversible_inplace: boost::integral_constant<bool,
|
||||
boost::is_integral<T>::value || boost::is_enum<T>::value || boost::is_same<T, float>::value || boost::is_same<T, double>::value>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Requires:
|
||||
// T is non-bool integral or scoped enumeration type
|
||||
|
||||
template<class T> inline BOOST_CONSTEXPR
|
||||
typename enable_if_< !is_class<T>::value, T >::type
|
||||
endian_reverse( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible<T>::value );
|
||||
|
||||
typedef typename detail::integral_by_size< sizeof(T) >::type uintN_t;
|
||||
|
||||
return static_cast<T>( detail::endian_reverse_impl( static_cast<uintN_t>( x ) ) );
|
||||
}
|
||||
|
||||
// Requires:
|
||||
// T is integral, enumeration, float or double
|
||||
|
||||
template<class T> inline
|
||||
typename enable_if_< !is_class<T>::value >::type
|
||||
endian_reverse_inplace( T & x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<T>::value );
|
||||
|
||||
typename detail::integral_by_size< sizeof(T) >::type x2;
|
||||
|
||||
std::memcpy( &x2, &x, sizeof(T) );
|
||||
|
||||
x2 = detail::endian_reverse_impl( x2 );
|
||||
|
||||
std::memcpy( &x, &x2, sizeof(T) );
|
||||
}
|
||||
|
||||
// Default implementation for user-defined types
|
||||
|
||||
template<class T> inline
|
||||
typename enable_if_< is_class<T>::value >::type
|
||||
endian_reverse_inplace( T & x ) BOOST_NOEXCEPT
|
||||
{
|
||||
x = endian_reverse( x );
|
||||
}
|
||||
|
||||
// endian_reverse_inplace for arrays
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline void endian_reverse_inplace( T (&x)[ N ] ) BOOST_NOEXCEPT
|
||||
{
|
||||
for( std::size_t i = 0; i < N; ++i )
|
||||
{
|
||||
endian_reverse_inplace( x[i] );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
|
442
include/boost/endian/detail/endian_store.hpp
Normal file
442
include/boost/endian/detail/endian_store.hpp
Normal file
@ -0,0 +1,442 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/detail/endian_reverse.hpp>
|
||||
#include <boost/endian/detail/order.hpp>
|
||||
#include <boost/endian/detail/integral_by_size.hpp>
|
||||
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, BOOST_SCOPED_ENUM(order) O2> struct endian_store_impl
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Requires:
|
||||
//
|
||||
// sizeof(T) must be 1, 2, 4, or 8
|
||||
// 1 <= N <= sizeof(T)
|
||||
// T is TriviallyCopyable
|
||||
// if N < sizeof(T), T is integral or enum
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
||||
inline void endian_store( unsigned char * p, T const & v ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 );
|
||||
BOOST_STATIC_ASSERT( N >= 1 && N <= sizeof(T) );
|
||||
|
||||
return detail::endian_store_impl<T, sizeof(T), order::native, N, Order>()( p, v );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// same endianness, same size
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_store_impl<T, N, O, N, O>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
std::memcpy( p, &v, N );
|
||||
}
|
||||
};
|
||||
|
||||
// same size, reverse endianness
|
||||
|
||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(order) O2> struct endian_store_impl<T, N, O1, N, O2>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
typename integral_by_size<N>::type tmp;
|
||||
std::memcpy( &tmp, &v, N );
|
||||
|
||||
endian_reverse_inplace( tmp );
|
||||
|
||||
std::memcpy( p, &tmp, N );
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 2 -> 1
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 2, Order, 1, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 2 ];
|
||||
boost::endian::endian_store<T, 2, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 2, Order, 1, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 2 ];
|
||||
boost::endian::endian_store<T, 2, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[1];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 4 -> 1
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 1, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 1, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[3];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 4 -> 2
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 2, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 2, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[2];
|
||||
p[1] = tmp[3];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 4 -> 3
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 3, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4, Order, 3, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
boost::endian::endian_store<T, 4, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[1];
|
||||
p[1] = tmp[2];
|
||||
p[2] = tmp[3];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 1
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 1, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 1, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 2
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 2, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 2, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[6];
|
||||
p[1] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 3
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 3, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 3, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[5];
|
||||
p[1] = tmp[6];
|
||||
p[2] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 4
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 4, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
p[3] = tmp[3];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 4, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[4];
|
||||
p[1] = tmp[5];
|
||||
p[2] = tmp[6];
|
||||
p[3] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 5
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 5, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
p[3] = tmp[3];
|
||||
p[4] = tmp[4];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 5, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[3];
|
||||
p[1] = tmp[4];
|
||||
p[2] = tmp[5];
|
||||
p[3] = tmp[6];
|
||||
p[4] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 6
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 6, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
p[3] = tmp[3];
|
||||
p[4] = tmp[4];
|
||||
p[5] = tmp[5];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 6, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[2];
|
||||
p[1] = tmp[3];
|
||||
p[2] = tmp[4];
|
||||
p[3] = tmp[5];
|
||||
p[4] = tmp[6];
|
||||
p[5] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
// truncating store 8 -> 7
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 7, order::little>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::little>( tmp, v );
|
||||
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
p[3] = tmp[3];
|
||||
p[4] = tmp[4];
|
||||
p[5] = tmp[5];
|
||||
p[6] = tmp[6];
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8, Order, 7, order::big>
|
||||
{
|
||||
inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
boost::endian::endian_store<T, 8, order::big>( tmp, v );
|
||||
|
||||
p[0] = tmp[1];
|
||||
p[1] = tmp[2];
|
||||
p[2] = tmp[3];
|
||||
p[3] = tmp[4];
|
||||
p[4] = tmp[5];
|
||||
p[5] = tmp[6];
|
||||
p[6] = tmp[7];
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_ENDIAN_STORE_HPP_INCLUDED
|
57
include/boost/endian/detail/integral_by_size.hpp
Normal file
57
include/boost/endian/detail/integral_by_size.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_INTEGRAL_BY_SIZE_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_INTEGRAL_BY_SIZE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<std::size_t N> struct integral_by_size
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct integral_by_size<1>
|
||||
{
|
||||
typedef uint8_t type;
|
||||
};
|
||||
|
||||
template<> struct integral_by_size<2>
|
||||
{
|
||||
typedef uint16_t type;
|
||||
};
|
||||
|
||||
template<> struct integral_by_size<4>
|
||||
{
|
||||
typedef uint32_t type;
|
||||
};
|
||||
|
||||
template<> struct integral_by_size<8>
|
||||
{
|
||||
typedef uint64_t type;
|
||||
};
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
template<> struct integral_by_size<16>
|
||||
{
|
||||
typedef uint128_type type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_INTEGRAL_BY_SIZE_HPP_INCLUDED
|
@ -18,8 +18,19 @@
|
||||
#define __has_builtin(x) 0 // Compatibility with non-clang compilers
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && ( !defined(__clang__) || defined(__c2__) )
|
||||
// Microsoft documents these as being compatible since Windows 95 and specifically
|
||||
// lists runtime library support since Visual Studio 2003 (aka 7.1).
|
||||
// Clang/c2 uses the Microsoft rather than GCC intrinsics, so we check for
|
||||
// defined(_MSC_VER) before defined(__clang__)
|
||||
# define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc."
|
||||
# include <cstdlib>
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x)
|
||||
|
||||
// GCC and Clang recent versions provide intrinsic byte swaps via builtins
|
||||
#if (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \
|
||||
#elif (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \
|
||||
|| (defined(__GNUC__ ) && \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
# define BOOST_ENDIAN_INTRINSIC_MSG "__builtin_bswap16, etc."
|
||||
@ -35,7 +46,9 @@
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) __builtin_bswap32(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) __builtin_bswap64(x)
|
||||
|
||||
// Linux systems provide the byteswap.h header, with
|
||||
# define BOOST_ENDIAN_CONSTEXPR_INTRINSICS
|
||||
|
||||
// Linux systems provide the byteswap.h header, with
|
||||
#elif defined(__linux__)
|
||||
// don't check for obsolete forms defined(linux) and defined(__linux) on the theory that
|
||||
// compilers that predefine only these are so old that byteswap.h probably isn't present.
|
||||
@ -45,14 +58,6 @@
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) bswap_32(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) bswap_64(x)
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
// Microsoft documents these as being compatible since Windows 95 and specificly
|
||||
// lists runtime library support since Visual Studio 2003 (aka 7.1).
|
||||
# define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc."
|
||||
# include <cstdlib>
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x)
|
||||
# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x)
|
||||
#else
|
||||
# define BOOST_ENDIAN_NO_INTRINSICS
|
||||
# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics"
|
||||
|
35
include/boost/endian/detail/is_scoped_enum.hpp
Normal file
35
include/boost/endian/detail/is_scoped_enum.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_IS_SCOPED_ENUM_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_IS_SCOPED_ENUM_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct negation: boost::integral_constant<bool, !T::value> {};
|
||||
|
||||
template<class T> struct is_scoped_enum:
|
||||
boost::conditional<
|
||||
boost::is_enum<T>::value,
|
||||
negation< boost::is_convertible<T, int> >,
|
||||
boost::false_type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_IS_SCOPED_ENUM_HPP_INCLUDED
|
40
include/boost/endian/detail/is_trivially_copyable.hpp
Normal file
40
include/boost/endian/detail/is_trivially_copyable.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
# include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
|
||||
using std::is_trivially_copyable;
|
||||
|
||||
#else
|
||||
|
||||
template<class T> struct is_trivially_copyable: boost::integral_constant<bool,
|
||||
boost::has_trivial_copy<T>::value && boost::has_trivial_assign<T>::value && boost::has_trivial_destructor<T>::value> {};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
59
include/boost/endian/detail/order.hpp
Normal file
59
include/boost/endian/detail/order.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_ORDER_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_ORDER_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
||||
# define BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER little
|
||||
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
# define BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER big
|
||||
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
|
||||
|
||||
# error The Boost.Endian library does not support platforms with PDP endianness.
|
||||
|
||||
#elif defined(__LITTLE_ENDIAN__)
|
||||
|
||||
# define BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER little
|
||||
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
|
||||
# define BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER big
|
||||
|
||||
#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
# define BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER little
|
||||
|
||||
#else
|
||||
|
||||
# error The Boost.Endian library could not determine the endianness of this platform.
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
BOOST_SCOPED_ENUM_START(order)
|
||||
{
|
||||
big,
|
||||
little,
|
||||
native = BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER
|
||||
|
||||
}; BOOST_SCOPED_ENUM_END
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_ORDER_HPP_INCLUDED
|
118
include/boost/endian/endian.hpp
Normal file
118
include/boost/endian/endian.hpp
Normal file
@ -0,0 +1,118 @@
|
||||
// boost/endian/endian.hpp -----------------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2015
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// See library home page at http://www.boost.org/libs/endian
|
||||
|
||||
#ifndef BOOST_ENDIAN_ENDIAN_HPP
|
||||
#define BOOST_ENDIAN_ENDIAN_HPP
|
||||
|
||||
#ifndef BOOST_ENDIAN_DEPRECATED_NAMES
|
||||
# error "<boost/endian/endian.hpp> is deprecated. Define BOOST_ENDIAN_DEPRECATED_NAMES to use."
|
||||
#endif
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
|
||||
BOOST_HEADER_DEPRECATED( "<boost/endian/arithmetic.hpp>" )
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
typedef order endianness;
|
||||
typedef align alignment;
|
||||
|
||||
# ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
|
||||
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(align) Align = align::no>
|
||||
using endian = endian_arithmetic<Order, T, n_bits, Align>;
|
||||
# endif
|
||||
|
||||
// unaligned big endian signed integer types
|
||||
typedef endian_arithmetic< order::big, int_least8_t, 8 > big8_t;
|
||||
typedef endian_arithmetic< order::big, int_least16_t, 16 > big16_t;
|
||||
typedef endian_arithmetic< order::big, int_least32_t, 24 > big24_t;
|
||||
typedef endian_arithmetic< order::big, int_least32_t, 32 > big32_t;
|
||||
typedef endian_arithmetic< order::big, int_least64_t, 40 > big40_t;
|
||||
typedef endian_arithmetic< order::big, int_least64_t, 48 > big48_t;
|
||||
typedef endian_arithmetic< order::big, int_least64_t, 56 > big56_t;
|
||||
typedef endian_arithmetic< order::big, int_least64_t, 64 > big64_t;
|
||||
|
||||
// unaligned big endian_arithmetic unsigned integer types
|
||||
typedef endian_arithmetic< order::big, uint_least8_t, 8 > ubig8_t;
|
||||
typedef endian_arithmetic< order::big, uint_least16_t, 16 > ubig16_t;
|
||||
typedef endian_arithmetic< order::big, uint_least32_t, 24 > ubig24_t;
|
||||
typedef endian_arithmetic< order::big, uint_least32_t, 32 > ubig32_t;
|
||||
typedef endian_arithmetic< order::big, uint_least64_t, 40 > ubig40_t;
|
||||
typedef endian_arithmetic< order::big, uint_least64_t, 48 > ubig48_t;
|
||||
typedef endian_arithmetic< order::big, uint_least64_t, 56 > ubig56_t;
|
||||
typedef endian_arithmetic< order::big, uint_least64_t, 64 > ubig64_t;
|
||||
|
||||
// unaligned little endian_arithmetic signed integer types
|
||||
typedef endian_arithmetic< order::little, int_least8_t, 8 > little8_t;
|
||||
typedef endian_arithmetic< order::little, int_least16_t, 16 > little16_t;
|
||||
typedef endian_arithmetic< order::little, int_least32_t, 24 > little24_t;
|
||||
typedef endian_arithmetic< order::little, int_least32_t, 32 > little32_t;
|
||||
typedef endian_arithmetic< order::little, int_least64_t, 40 > little40_t;
|
||||
typedef endian_arithmetic< order::little, int_least64_t, 48 > little48_t;
|
||||
typedef endian_arithmetic< order::little, int_least64_t, 56 > little56_t;
|
||||
typedef endian_arithmetic< order::little, int_least64_t, 64 > little64_t;
|
||||
|
||||
// unaligned little endian_arithmetic unsigned integer types
|
||||
typedef endian_arithmetic< order::little, uint_least8_t, 8 > ulittle8_t;
|
||||
typedef endian_arithmetic< order::little, uint_least16_t, 16 > ulittle16_t;
|
||||
typedef endian_arithmetic< order::little, uint_least32_t, 24 > ulittle24_t;
|
||||
typedef endian_arithmetic< order::little, uint_least32_t, 32 > ulittle32_t;
|
||||
typedef endian_arithmetic< order::little, uint_least64_t, 40 > ulittle40_t;
|
||||
typedef endian_arithmetic< order::little, uint_least64_t, 48 > ulittle48_t;
|
||||
typedef endian_arithmetic< order::little, uint_least64_t, 56 > ulittle56_t;
|
||||
typedef endian_arithmetic< order::little, uint_least64_t, 64 > ulittle64_t;
|
||||
|
||||
// unaligned native endian_arithmetic signed integer types
|
||||
typedef endian_arithmetic< order::native, int_least8_t, 8 > native8_t;
|
||||
typedef endian_arithmetic< order::native, int_least16_t, 16 > native16_t;
|
||||
typedef endian_arithmetic< order::native, int_least32_t, 24 > native24_t;
|
||||
typedef endian_arithmetic< order::native, int_least32_t, 32 > native32_t;
|
||||
typedef endian_arithmetic< order::native, int_least64_t, 40 > native40_t;
|
||||
typedef endian_arithmetic< order::native, int_least64_t, 48 > native48_t;
|
||||
typedef endian_arithmetic< order::native, int_least64_t, 56 > native56_t;
|
||||
typedef endian_arithmetic< order::native, int_least64_t, 64 > native64_t;
|
||||
|
||||
// unaligned native endian_arithmetic unsigned integer types
|
||||
typedef endian_arithmetic< order::native, uint_least8_t, 8 > unative8_t;
|
||||
typedef endian_arithmetic< order::native, uint_least16_t, 16 > unative16_t;
|
||||
typedef endian_arithmetic< order::native, uint_least32_t, 24 > unative24_t;
|
||||
typedef endian_arithmetic< order::native, uint_least32_t, 32 > unative32_t;
|
||||
typedef endian_arithmetic< order::native, uint_least64_t, 40 > unative40_t;
|
||||
typedef endian_arithmetic< order::native, uint_least64_t, 48 > unative48_t;
|
||||
typedef endian_arithmetic< order::native, uint_least64_t, 56 > unative56_t;
|
||||
typedef endian_arithmetic< order::native, uint_least64_t, 64 > unative64_t;
|
||||
|
||||
// aligned native endian_arithmetic typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
typedef endian_arithmetic< order::big, int16_t, 16, align::yes > aligned_big16_t;
|
||||
typedef endian_arithmetic< order::big, uint16_t, 16, align::yes > aligned_ubig16_t;
|
||||
typedef endian_arithmetic< order::little, int16_t, 16, align::yes > aligned_little16_t;
|
||||
typedef endian_arithmetic< order::little, uint16_t, 16, align::yes > aligned_ulittle16_t;
|
||||
|
||||
typedef endian_arithmetic< order::big, int32_t, 32, align::yes > aligned_big32_t;
|
||||
typedef endian_arithmetic< order::big, uint32_t, 32, align::yes > aligned_ubig32_t;
|
||||
typedef endian_arithmetic< order::little, int32_t, 32, align::yes > aligned_little32_t;
|
||||
typedef endian_arithmetic< order::little, uint32_t, 32, align::yes > aligned_ulittle32_t;
|
||||
|
||||
typedef endian_arithmetic< order::big, int64_t, 64, align::yes > aligned_big64_t;
|
||||
typedef endian_arithmetic< order::big, uint64_t, 64, align::yes > aligned_ubig64_t;
|
||||
typedef endian_arithmetic< order::little, int64_t, 64, align::yes > aligned_little64_t;
|
||||
typedef endian_arithmetic< order::little, uint64_t, 64, align::yes > aligned_ulittle64_t;
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#endif //BOOST_ENDIAN_ENDIAN_HPP
|
@ -1,38 +0,0 @@
|
||||
// boost/endian/std_pair.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2013
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_ENDIAN_STD_PAIR_HPP
|
||||
#define BOOST_ENDIAN_STD_PAIR_HPP
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
template <class ReversibleValueT, class ReversibleValueU>
|
||||
std::pair<ReversibleValueT, ReversibleValueU>
|
||||
reverse_value(std::pair<ReversibleValueT, ReversibleValueU> x)
|
||||
{
|
||||
return std::pair<ReversibleValueT, ReversibleValueU>(reverse_value(x.first),
|
||||
reverse_value(x.second));
|
||||
}
|
||||
|
||||
template <class ReversibleT, class ReversibleU>
|
||||
void reverse(std::pair<ReversibleT, ReversibleU>& x)
|
||||
{
|
||||
reverse(x.first);
|
||||
reverse(x.second);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_ENDIAN_STD_PAIR_HPP
|
18
index.html
18
index.html
@ -1,14 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/endian.html">
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="doc/index.html">doc/index.html</a>. <hr>
|
||||
<p><font size="2"><EFBFBD> Copyright Beman Dawes, 2001</font></p>
|
||||
<p><font size="2">Distributed under the Boost Software License, Version 1.0.
|
||||
(See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</font>
|
||||
<a href="doc/html/endian.html">doc/html/endian.html</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
<!--
|
||||
Copyright 2001 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
@ -5,12 +5,13 @@
|
||||
"Beman Dawes"
|
||||
],
|
||||
"maintainers": [
|
||||
"Beman Dawes <bdawes -at- acm.org>"
|
||||
"Peter Dimov <pdimov -at- gmail.com>"
|
||||
],
|
||||
"description": "Types and conversion functions for correct byte ordering and more regardless of processor endianness.",
|
||||
"category": [
|
||||
"IO",
|
||||
"Math",
|
||||
"Miscellaneous"
|
||||
]
|
||||
],
|
||||
"cxxstd": "03"
|
||||
}
|
||||
|
11
test/CMakeLists.txt
Normal file
11
test/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# Copyright 2018, 2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
||||
|
||||
if(HAVE_BOOST_TEST)
|
||||
|
||||
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::endian Boost::core)
|
||||
|
||||
endif()
|
118
test/Jamfile.v2
118
test/Jamfile.v2
@ -1,27 +1,111 @@
|
||||
# Boost Endian Library test Jamfile
|
||||
|
||||
# Copyright Beman Dawes 2006, 2013
|
||||
# Copyright 2018, 2019 Peter Dimov
|
||||
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
# See library home page at http://www.boost.org/libs/endian
|
||||
|
||||
import testing ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
;
|
||||
|
||||
test-suite "endian"
|
||||
:
|
||||
[ run buffer_test.cpp # sources
|
||||
: # command line
|
||||
: # input files
|
||||
: # requirements
|
||||
: # target name
|
||||
]
|
||||
[ run endian_test.cpp ]
|
||||
[ run endian_operations_test.cpp ]
|
||||
[ run endian_in_union_test.cpp ]
|
||||
[ run conversion_test.cpp ]
|
||||
;
|
||||
: default-build
|
||||
|
||||
<warnings>pedantic
|
||||
|
||||
: requirements
|
||||
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
|
||||
<toolset>gcc:<cxxflags>-Wno-long-long
|
||||
<toolset>gcc-4.4:<cxxflags>-Wno-strict-aliasing
|
||||
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare
|
||||
<toolset>gcc:<warnings-as-errors>on
|
||||
|
||||
<toolset>clang:<cxxflags>-Wno-long-long
|
||||
<toolset>clang:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
local rule run-ni ( sources + )
|
||||
{
|
||||
return [ run $(sources) : : : <define>BOOST_ENDIAN_NO_INTRINSICS : $(sources[1]:B)_ni ] ;
|
||||
}
|
||||
|
||||
run buffer_test.cpp ;
|
||||
run-ni buffer_test.cpp ;
|
||||
|
||||
run endian_test.cpp ;
|
||||
run-ni endian_test.cpp ;
|
||||
|
||||
run endian_operations_test.cpp ;
|
||||
run-ni endian_operations_test.cpp ;
|
||||
|
||||
run endian_in_union_test.cpp ;
|
||||
|
||||
run conversion_test.cpp ;
|
||||
run-ni conversion_test.cpp ;
|
||||
|
||||
run intrinsic_test.cpp ;
|
||||
|
||||
run quick.cpp ;
|
||||
|
||||
run endian_reverse_test.cpp ;
|
||||
run-ni endian_reverse_test.cpp ;
|
||||
|
||||
run endian_load_test.cpp ;
|
||||
run-ni endian_load_test.cpp ;
|
||||
|
||||
run endian_store_test.cpp ;
|
||||
run-ni endian_store_test.cpp ;
|
||||
|
||||
run endian_ld_st_roundtrip_test.cpp ;
|
||||
run-ni endian_ld_st_roundtrip_test.cpp ;
|
||||
|
||||
run endian_arithmetic_test.cpp
|
||||
: : : "<toolset>gcc,<address-model>32:<cxxflags>-ffloat-store" ;
|
||||
run endian_arithmetic_test.cpp : : :
|
||||
"<toolset>gcc,<address-model>32:<cxxflags>-ffloat-store" <define>BOOST_ENDIAN_NO_INTRINSICS : endian_arithmetic_test_ni ;
|
||||
|
||||
run deprecated_test.cpp ;
|
||||
|
||||
compile endian_reverse_cx_test.cpp ;
|
||||
compile endian_reverse_cx_test.cpp : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_reverse_cx_test_ni ;
|
||||
|
||||
run load_convenience_test.cpp ;
|
||||
run-ni load_convenience_test.cpp ;
|
||||
|
||||
run store_convenience_test.cpp ;
|
||||
run-ni store_convenience_test.cpp ;
|
||||
|
||||
run float_typedef_test.cpp
|
||||
: : : "<toolset>gcc,<address-model>32:<cxxflags>-ffloat-store" ;
|
||||
run float_typedef_test.cpp : : :
|
||||
"<toolset>gcc,<address-model>32:<cxxflags>-ffloat-store" <define>BOOST_ENDIAN_NO_INTRINSICS : float_typedef_test_ni ;
|
||||
|
||||
run data_test.cpp ;
|
||||
run-ni data_test.cpp ;
|
||||
|
||||
run endian_hpp_test.cpp ;
|
||||
run-ni endian_hpp_test.cpp ;
|
||||
|
||||
run order_test.cpp ;
|
||||
|
||||
run endian_reverse_test2.cpp ;
|
||||
run-ni endian_reverse_test2.cpp ;
|
||||
|
||||
run is_scoped_enum_test.cpp ;
|
||||
|
||||
run endian_reverse_test3.cpp ;
|
||||
run-ni endian_reverse_test3.cpp ;
|
||||
|
||||
run endian_reverse_test4.cpp ;
|
||||
run-ni endian_reverse_test4.cpp ;
|
||||
|
||||
run endian_reverse_test5.cpp ;
|
||||
run-ni endian_reverse_test5.cpp ;
|
||||
|
||||
run packed_buffer_test.cpp ;
|
||||
run arithmetic_buffer_test.cpp ;
|
||||
run packed_arithmetic_test.cpp ;
|
||||
|
45
test/arithmetic_buffer_test.cpp
Normal file
45
test/arithmetic_buffer_test.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
template<class A, class B> void test()
|
||||
{
|
||||
A a( 5 );
|
||||
BOOST_TEST_EQ( a.value(), 5 );
|
||||
|
||||
B& b = a;
|
||||
BOOST_TEST_EQ( b.value(), 5 );
|
||||
|
||||
b = 14;
|
||||
BOOST_TEST_EQ( b.value(), 14 );
|
||||
BOOST_TEST_EQ( a.value(), 14 );
|
||||
|
||||
A const& ca = a;
|
||||
BOOST_TEST_EQ( ca.value(), 14 );
|
||||
|
||||
B const& cb = b;
|
||||
BOOST_TEST_EQ( cb.value(), 14 );
|
||||
|
||||
a = 31;
|
||||
|
||||
BOOST_TEST_EQ( a.value(), 31 );
|
||||
BOOST_TEST_EQ( b.value(), 31 );
|
||||
|
||||
BOOST_TEST_EQ( ca.value(), 31 );
|
||||
BOOST_TEST_EQ( cb.value(), 31 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
test<big_int16_t, big_int16_buf_t>();
|
||||
test<little_int32_t, little_int32_buf_t>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -41,24 +41,24 @@ namespace
|
||||
#endif
|
||||
|
||||
typedef boost::timer::nanosecond_type nanosecond_t;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
nanosecond_t benchmark(timee_func timee, const char* msg,
|
||||
nanosecond_t overhead = 0)
|
||||
// Returns: total cpu time (i.e. system time + user time)
|
||||
{
|
||||
if (verbose)
|
||||
cout << "\nRunning benchmark..." << endl;
|
||||
int64_t sum = 0;
|
||||
{
|
||||
if (verbose)
|
||||
cout << "\nRunning benchmark..." << endl;
|
||||
int64_t sum = 0;
|
||||
boost::timer::cpu_times times;
|
||||
nanosecond_t cpu_time;
|
||||
boost::timer::auto_cpu_timer t(places);
|
||||
|
||||
for (long long i = n_cases; i; --i)
|
||||
{
|
||||
boost::timer::auto_cpu_timer t(places);
|
||||
|
||||
for (long long i = n_cases; i; --i)
|
||||
{
|
||||
# ifndef BOOST_TWO_ARG
|
||||
sum += timee(static_cast<int32_t>(i)) ;
|
||||
sum += timee(static_cast<int32_t>(i)) ;
|
||||
# else
|
||||
int32_t y;
|
||||
timee(static_cast<int32_t>(i), y);
|
||||
@ -71,13 +71,13 @@ namespace
|
||||
const long double sec = 1000000000.0L;
|
||||
cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
|
||||
cout.precision(places);
|
||||
cout << msg << " " << cpu_time / sec << endl;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
cout << msg << " " << cpu_time / sec << endl;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
t.report();
|
||||
cout << " Benchmark complete\n"
|
||||
" sum is " << sum << endl;
|
||||
cout << " Benchmark complete\n"
|
||||
" sum is " << sum << endl;
|
||||
}
|
||||
return cpu_time;
|
||||
}
|
||||
@ -100,7 +100,7 @@ namespace
|
||||
n_cases = _atoi64(argv[1]);
|
||||
#endif
|
||||
|
||||
for (; argc > 2; ++argv, --argc)
|
||||
for (; argc > 2; ++argv, --argc)
|
||||
{
|
||||
if ( *(argv[2]+1) == 'p' )
|
||||
places = atoi( argv[2]+2 );
|
||||
@ -114,7 +114,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: benchmark n [Options]\n"
|
||||
" The argument n specifies the number of test cases to run\n"
|
||||
@ -211,7 +211,7 @@ namespace
|
||||
|
||||
//-------------------------------------- main() ---------------------------------------//
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
process_command_line(argc, argv);
|
||||
|
||||
|
@ -11,34 +11,327 @@
|
||||
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#define BOOST_ENDIAN_LOG
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
|
||||
namespace bel = boost::endian;
|
||||
using namespace boost::endian;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// check_size ------------------------------------------------------------//
|
||||
|
||||
void check_size()
|
||||
{
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_int8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(big_int16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(big_int24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(big_int32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_int40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(big_int48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(big_int56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(big_int64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_uint8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_float32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_float64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_int8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(little_int16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(little_int24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(little_int32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_int40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(little_int48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(little_int56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(little_int64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_uint8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_float32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_float64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(native_int8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(native_int16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(native_int24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(native_int32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(native_int40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(native_int48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(native_int56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(native_int64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(native_uint8_buf_t), 1u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint16_buf_t), 2u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint24_buf_t), 3u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint40_buf_t), 5u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint48_buf_t), 6u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint56_buf_t), 7u);
|
||||
BOOST_TEST_EQ(sizeof(native_uint64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(native_float32_buf_t), 4u);
|
||||
BOOST_TEST_EQ(sizeof(native_float64_buf_t), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_int8_buf_at), 1u);
|
||||
BOOST_TEST_EQ(sizeof(big_int16_buf_at), 2u);
|
||||
BOOST_TEST_EQ(sizeof(big_int32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_int64_buf_at), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_uint8_buf_at), 1u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint16_buf_at), 2u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_uint64_buf_at), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(big_float32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(big_float64_buf_at), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_int8_buf_at), 1u);
|
||||
BOOST_TEST_EQ(sizeof(little_int16_buf_at), 2u);
|
||||
BOOST_TEST_EQ(sizeof(little_int32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_int64_buf_at), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_uint8_buf_at), 1u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint16_buf_at), 2u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_uint64_buf_at), 8u);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little_float32_buf_at), 4u);
|
||||
BOOST_TEST_EQ(sizeof(little_float64_buf_at), 8u);
|
||||
|
||||
} // check_size
|
||||
|
||||
// test_inserter_and_extractor -----------------------------------------------------//
|
||||
|
||||
void test_inserter_and_extractor()
|
||||
{
|
||||
std::cout << "test inserter and extractor..." << std::endl;
|
||||
|
||||
big_uint64_buf_t bu64(0x010203040506070ULL);
|
||||
little_uint64_buf_t lu64(0x010203040506070ULL);
|
||||
|
||||
boost::uint64_t x;
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << bu64;
|
||||
ss >> x;
|
||||
BOOST_TEST_EQ(x, 0x010203040506070ULL);
|
||||
|
||||
ss.clear();
|
||||
ss << lu64;
|
||||
ss >> x;
|
||||
BOOST_TEST_EQ(x, 0x010203040506070ULL);
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
big_uint64_buf_t bu64z(0);
|
||||
ss >> bu64z;
|
||||
BOOST_TEST_EQ(bu64z.value(), bu64.value());
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
little_uint64_buf_t lu64z(0);
|
||||
ss >> lu64z;
|
||||
BOOST_TEST_EQ(lu64z.value(), lu64.value());
|
||||
|
||||
std::cout << "test inserter and extractor complete" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
template<class T> struct unaligned
|
||||
{
|
||||
char x;
|
||||
T y;
|
||||
};
|
||||
|
||||
template<class T> void test_buffer_type( typename T::value_type v1, typename T::value_type v2 )
|
||||
{
|
||||
T buffer( v1 );
|
||||
BOOST_TEST_EQ( buffer.value(), v1 );
|
||||
|
||||
buffer = v2;
|
||||
BOOST_TEST_EQ( buffer.value(), v2 );
|
||||
|
||||
unaligned<T> buffer2 = { 0, T( v1 ) };
|
||||
BOOST_TEST_EQ( buffer2.y.value(), v1 );
|
||||
|
||||
buffer2.y = v2;
|
||||
BOOST_TEST_EQ( buffer2.y.value(), v2 );
|
||||
}
|
||||
|
||||
void test_construction_and_assignment()
|
||||
{
|
||||
std::cout << "test construction and assignment..." << std::endl;
|
||||
|
||||
test_buffer_type< big_int8_buf_at>( 0x01, -0x01 );
|
||||
test_buffer_type<big_int16_buf_at>( 0x0102, -0x0102 );
|
||||
test_buffer_type<big_int32_buf_at>( 0x01020304, -0x01020304 );
|
||||
test_buffer_type<big_int64_buf_at>( 0x0102030405060708LL, -0x0102030405060708LL );
|
||||
|
||||
test_buffer_type< big_uint8_buf_at>( 0x01, 0xFE );
|
||||
test_buffer_type<big_uint16_buf_at>( 0x0102, 0xFE02 );
|
||||
test_buffer_type<big_uint32_buf_at>( 0x01020304, 0xFE020304 );
|
||||
test_buffer_type<big_uint64_buf_at>( 0x0102030405060708ULL, 0xFE02030405060708ULL );
|
||||
|
||||
test_buffer_type<big_float32_buf_at>( +1.5f, -3.14f );
|
||||
test_buffer_type<big_float64_buf_at>( +1.5, -3.14 );
|
||||
|
||||
test_buffer_type< little_int8_buf_at>( 0x01, -0x01 );
|
||||
test_buffer_type<little_int16_buf_at>( 0x0102, -0x0102 );
|
||||
test_buffer_type<little_int32_buf_at>( 0x01020304, -0x01020304 );
|
||||
test_buffer_type<little_int64_buf_at>( 0x0102030405060708LL, -0x0102030405060708LL );
|
||||
|
||||
test_buffer_type< little_uint8_buf_at>( 0x01, 0xFE );
|
||||
test_buffer_type<little_uint16_buf_at>( 0x0102, 0xFE02 );
|
||||
test_buffer_type<little_uint32_buf_at>( 0x01020304, 0xFE020304 );
|
||||
test_buffer_type<little_uint64_buf_at>( 0x0102030405060708ULL, 0xFE02030405060708ULL );
|
||||
|
||||
test_buffer_type<little_float32_buf_at>( +1.5f, -3.14f );
|
||||
test_buffer_type<little_float64_buf_at>( +1.5, -3.14 );
|
||||
|
||||
test_buffer_type< big_int8_buf_t>( 0x01, -0x01 );
|
||||
test_buffer_type<big_int16_buf_t>( 0x0102, -0x0102 );
|
||||
test_buffer_type<big_int24_buf_t>( 0x010203, -0x010203 );
|
||||
test_buffer_type<big_int32_buf_t>( 0x01020304, -0x01020304 );
|
||||
test_buffer_type<big_int40_buf_t>( 0x0102030405LL, -0x0102030405LL );
|
||||
test_buffer_type<big_int48_buf_t>( 0x010203040506LL, -0x010203040506LL );
|
||||
test_buffer_type<big_int56_buf_t>( 0x01020304050607LL, -0x01020304050607LL );
|
||||
test_buffer_type<big_int64_buf_t>( 0x0102030405060708LL, -0x0102030405060708LL );
|
||||
|
||||
test_buffer_type<big_float32_buf_t>( +1.5f, -3.14f );
|
||||
test_buffer_type<big_float64_buf_t>( +1.5, -3.14 );
|
||||
|
||||
test_buffer_type< little_uint8_buf_t>( 0x01, 0xFE );
|
||||
test_buffer_type<little_uint16_buf_t>( 0x0102, 0xFE02 );
|
||||
test_buffer_type<little_uint24_buf_t>( 0x010203, 0xFE0203 );
|
||||
test_buffer_type<little_uint32_buf_t>( 0x01020304, 0xFE020304 );
|
||||
test_buffer_type<little_uint40_buf_t>( 0x0102030405ULL, 0xFE02030405ULL );
|
||||
test_buffer_type<little_uint48_buf_t>( 0x010203040506ULL, 0xFE0203040506ULL );
|
||||
test_buffer_type<little_uint56_buf_t>( 0x01020304050607ULL, 0xFE020304050607ULL );
|
||||
test_buffer_type<little_uint64_buf_t>( 0x0102030405060708ULL, 0xFE02030405060708ULL );
|
||||
|
||||
test_buffer_type<little_float32_buf_t>( +1.5f, -3.14f );
|
||||
test_buffer_type<little_float64_buf_t>( +1.5, -3.14 );
|
||||
|
||||
std::cout << "test construction and assignment complete" << std::endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_boundary_values_()
|
||||
{
|
||||
test_buffer_type< endian_buffer<order::big, T, sizeof(T) * CHAR_BIT, align::no > >( std::numeric_limits<T>::min(), std::numeric_limits<T>::max() );
|
||||
test_buffer_type< endian_buffer<order::little, T, sizeof(T) * CHAR_BIT, align::no > >( std::numeric_limits<T>::min(), std::numeric_limits<T>::max() );
|
||||
test_buffer_type< endian_buffer<order::big, T, sizeof(T) * CHAR_BIT, align::yes> >( std::numeric_limits<T>::min(), std::numeric_limits<T>::max() );
|
||||
test_buffer_type< endian_buffer<order::little, T, sizeof(T) * CHAR_BIT, align::yes> >( std::numeric_limits<T>::min(), std::numeric_limits<T>::max() );
|
||||
}
|
||||
|
||||
void test_boundary_values()
|
||||
{
|
||||
std::cout << "test boundary values..." << std::endl;
|
||||
|
||||
// integer types
|
||||
|
||||
test_boundary_values_<signed char>();
|
||||
test_boundary_values_<unsigned char>();
|
||||
test_boundary_values_<signed short>();
|
||||
test_boundary_values_<unsigned short>();
|
||||
test_boundary_values_<signed int>();
|
||||
test_boundary_values_<unsigned int>();
|
||||
test_boundary_values_<signed long>();
|
||||
test_boundary_values_<unsigned long>();
|
||||
test_boundary_values_<signed long long>();
|
||||
test_boundary_values_<unsigned long long>();
|
||||
|
||||
// character types
|
||||
|
||||
test_boundary_values_<char>();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
test_boundary_values_<char16_t>();
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
test_boundary_values_<char32_t>();
|
||||
#endif
|
||||
|
||||
// floating-point types
|
||||
|
||||
test_boundary_values_<float>();
|
||||
test_boundary_values_<double>();
|
||||
|
||||
std::cout << "test boundary values complete" << std::endl;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
int cpp_main(int, char *[])
|
||||
{
|
||||
cout << "byte swap intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG << endl;
|
||||
|
||||
cout << " construct" << endl;
|
||||
bel::big_int32_buf_t x(1122334455);
|
||||
cout << " construct big endian aligned" << endl;
|
||||
big_int32_buf_at x(1122334455);
|
||||
|
||||
cout << " assign from built-in integer" << endl;
|
||||
cout << " assign to buffer from built-in integer" << endl;
|
||||
x = 1234567890;
|
||||
|
||||
cout << " operator==(buffer, built-in)" << endl;
|
||||
cout << " operator==(buffer.value(), built-in)" << endl;
|
||||
bool b1(x.value() == 1234567890);
|
||||
BOOST_TEST(b1);
|
||||
|
||||
cout << " construct little endian unaligned" << endl;
|
||||
little_int32_buf_t x2(1122334455);
|
||||
|
||||
cout << " assign to buffer from built-in integer" << endl;
|
||||
x2 = 1234567890;
|
||||
|
||||
cout << " operator==(buffer.value(), built-in)" << endl;
|
||||
bool b2(x2.value() == 1234567890);
|
||||
BOOST_TEST(b2);
|
||||
|
||||
check_size();
|
||||
test_inserter_and_extractor();
|
||||
test_construction_and_assignment();
|
||||
test_boundary_values();
|
||||
|
||||
cout << " done" << endl;
|
||||
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main( argc, argv );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
BOOST_ERROR( x.what() );
|
||||
return boost::report_errors();
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/endian/detail/disable_warnings_pop.hpp>
|
||||
|
18
test/cmake_install_test/CMakeLists.txt
Normal file
18
test/cmake_install_test/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright 2018, 2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(cmake_install_test LANGUAGES CXX)
|
||||
|
||||
find_package(boost_endian REQUIRED)
|
||||
find_package(boost_core REQUIRED)
|
||||
|
||||
add_executable(quick ../quick.cpp)
|
||||
target_link_libraries(quick Boost::endian Boost::core)
|
||||
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
39
test/cmake_subdir_test/CMakeLists.txt
Normal file
39
test/cmake_subdir_test/CMakeLists.txt
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright 2018, 2019 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(cmake_subdir_test LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(../.. boostorg/endian)
|
||||
|
||||
# boost_add_subdir
|
||||
|
||||
function(boost_add_subdir name)
|
||||
|
||||
add_subdirectory(../../../${name} boostorg/${name})
|
||||
|
||||
endfunction()
|
||||
|
||||
# primary dependencies
|
||||
|
||||
boost_add_subdir(config)
|
||||
boost_add_subdir(core)
|
||||
boost_add_subdir(static_assert)
|
||||
boost_add_subdir(type_traits)
|
||||
|
||||
# secondary dependencies
|
||||
|
||||
boost_add_subdir(assert)
|
||||
boost_add_subdir(throw_exception)
|
||||
|
||||
# --target check
|
||||
|
||||
add_executable(quick ../quick.cpp)
|
||||
target_link_libraries(quick Boost::endian Boost::core)
|
||||
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
@ -7,13 +7,24 @@
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4127 ) // conditional expression is constant
|
||||
# if _MSC_VER < 1500
|
||||
# pragma warning( disable: 4267 ) // '+=': possible loss of data
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
namespace be = boost::endian;
|
||||
using std::cout;
|
||||
@ -27,103 +38,53 @@ using boost::uint32_t;
|
||||
using boost::int64_t;
|
||||
using boost::uint64_t;
|
||||
|
||||
template <class T> inline T std_endian_reverse(T x) BOOST_NOEXCEPT
|
||||
{
|
||||
T tmp(x);
|
||||
std::reverse( reinterpret_cast<unsigned char*>(&tmp), reinterpret_cast<unsigned char*>(&tmp) + sizeof(T) );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// values for tests
|
||||
// values for tests
|
||||
|
||||
void native_value(int8_t& x) {x = static_cast<int8_t>(0xF0U);}
|
||||
void native_value(uint8_t& x) {x = static_cast<uint8_t>(0xF0U);}
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
void big_value(int8_t& x) {x = static_cast<int8_t>(0xF0U);}
|
||||
void big_value(uint8_t& x) {x = static_cast<uint8_t>(0xF0U);}
|
||||
void little_value(int8_t& x) {x = static_cast<int8_t>(0xF0U);}
|
||||
void little_value(uint8_t& x) {x = static_cast<uint8_t>(0xF0U);}
|
||||
# else
|
||||
void big_value(int8_t& x) {x = static_cast<int8_t>(0xF0U);}
|
||||
void big_value(uint8_t& x) {x = static_cast<uint8_t>(0xF0U);}
|
||||
void little_value(int8_t& x) {x = static_cast<int8_t>(0xF0U);}
|
||||
void little_value(uint8_t& x) {x = static_cast<uint8_t>(0xF0U);}
|
||||
# endif
|
||||
static unsigned char const test_value_bytes[] = { 0xF1, 0x02, 0xE3, 0x04, 0xD5, 0x06, 0xC7, 0x08 };
|
||||
|
||||
void native_value(int16_t& x) {x = static_cast<int16_t>(0xF102U);}
|
||||
void native_value(uint16_t& x) {x = static_cast<uint16_t>(0xF102U);}
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
void big_value(int16_t& x) {x = static_cast<int16_t>(0xF102U);}
|
||||
void big_value(uint16_t& x) {x = static_cast<uint16_t>(0xF102U);}
|
||||
void little_value(int16_t& x) {x = static_cast<int16_t>(0x02F1U);}
|
||||
void little_value(uint16_t& x) {x = static_cast<uint16_t>(0x02F1U);}
|
||||
# else
|
||||
void big_value(int16_t& x) {x = static_cast<int16_t>(0x02F1U);}
|
||||
void big_value(uint16_t& x) {x = static_cast<uint16_t>(0x02F1U);}
|
||||
void little_value(int16_t& x) {x = static_cast<int16_t>(0xF102U);}
|
||||
void little_value(uint16_t& x) {x = static_cast<uint16_t>(0xF102U);}
|
||||
# endif
|
||||
template<class T> void native_value( T& x )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( boost::is_integral<T>::value && sizeof( T ) <= 8 );
|
||||
std::memcpy( &x, test_value_bytes, sizeof( x ) );
|
||||
}
|
||||
|
||||
void native_value(int32_t& x) {x = static_cast<int32_t>(0xF1E21304UL);}
|
||||
void native_value(uint32_t& x) {x = static_cast<uint32_t>(0xF1E21304UL);}
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
void big_value(int32_t& x) {x = static_cast<int32_t>(0xF1E21304UL);}
|
||||
void big_value(uint32_t& x) {x = static_cast<uint32_t>(0xF1E21304UL);}
|
||||
void little_value(int32_t& x) {x = static_cast<int32_t>(0x0413E2F1UL);}
|
||||
void little_value(uint32_t& x) {x = static_cast<uint32_t>(0x0413E2F1UL);}
|
||||
# else
|
||||
void big_value(int32_t& x) {x = static_cast<int32_t>(0x0413E2F1UL);}
|
||||
void big_value(uint32_t& x) {x = static_cast<uint32_t>(0x0413E2F1UL);}
|
||||
void little_value(int32_t& x) {x = static_cast<int32_t>(0xF1E21304UL);}
|
||||
void little_value(uint32_t& x) {x = static_cast<uint32_t>(0xF1E21304UL);}
|
||||
# endif
|
||||
template<class T> void little_value( T& x )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( boost::is_integral<T>::value && sizeof( T ) <= 8 );
|
||||
|
||||
void native_value(int64_t& x) {x = static_cast<int64_t>(0xF1E2D3C444231201ULL);}
|
||||
void native_value(uint64_t& x) {x = static_cast<uint64_t>(0xF1E2D3C444231201ULL);}
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
void big_value(int64_t& x) {x = static_cast<int64_t>(0xF1E2D3C444231201ULL);}
|
||||
void big_value(uint64_t& x) {x = static_cast<uint64_t>(0xF1E2D3C444231201ULL);}
|
||||
void little_value(int64_t& x) {x = static_cast<int64_t>(0x01122344C4D3E2F1ULL);}
|
||||
void little_value(uint64_t& x) {x = static_cast<uint64_t>(0x01122344C4D3E2F1ULL);}
|
||||
# else
|
||||
void big_value(int64_t& x) {x = static_cast<int64_t>(0x01122344C4D3E2F1ULL);}
|
||||
void big_value(uint64_t& x) {x = static_cast<uint64_t>(0x01122344C4D3E2F1ULL);}
|
||||
void little_value(int64_t& x) {x = static_cast<int64_t>(0xF1E2D3C444231201ULL);}
|
||||
void little_value(uint64_t& x) {x = static_cast<uint64_t>(0xF1E2D3C444231201ULL);}
|
||||
# endif
|
||||
typedef typename boost::make_unsigned<T>::type U;
|
||||
|
||||
const float float_value = -1.234F;
|
||||
const double double_value = -1.234567;
|
||||
x = 0;
|
||||
|
||||
void native_value(float& x) {std::memcpy(&x, &float_value, sizeof(float));}
|
||||
void native_value(double& x) {memcpy(&x, &double_value, sizeof(double));}
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
void big_value(float& x) {memcpy(&x, &float_value, sizeof(float));}
|
||||
void big_value(double& x) {memcpy(&x, &double_value, sizeof(double));}
|
||||
void little_value(float& x)
|
||||
{
|
||||
memcpy(&x, &float_value, sizeof(float));
|
||||
std::reverse(reinterpret_cast<char*>(&x),
|
||||
reinterpret_cast<char*>(&x)+sizeof(float));
|
||||
}
|
||||
void little_value(double& x)
|
||||
{
|
||||
memcpy(&x, &double_value, sizeof(double));
|
||||
std::reverse(reinterpret_cast<char*>(&x),
|
||||
reinterpret_cast<char*>(&x)+sizeof(double));
|
||||
}
|
||||
# else
|
||||
void big_value(float& x)
|
||||
{
|
||||
memcpy(&x, &float_value, sizeof(float));
|
||||
std::reverse(reinterpret_cast<char*>(&x),
|
||||
reinterpret_cast<char*>(&x)+sizeof(float));
|
||||
}
|
||||
void big_value(double& x)
|
||||
{
|
||||
memcpy(&x, &double_value, sizeof(double));
|
||||
std::reverse(reinterpret_cast<char*>(&x),
|
||||
reinterpret_cast<char*>(&x)+sizeof(double));
|
||||
}
|
||||
void little_value(float& x) {memcpy(&x, &float_value, sizeof(float));}
|
||||
void little_value(double& x) {memcpy(&x, &double_value, sizeof(double));}
|
||||
# endif
|
||||
for( std::size_t i = 0; i < sizeof( x ); ++i )
|
||||
{
|
||||
x += static_cast<U>( test_value_bytes[ i ] ) << ( 8 * i );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void big_value( T& x )
|
||||
{
|
||||
BOOST_STATIC_ASSERT( boost::is_integral<T>::value && sizeof( T ) <= 8 );
|
||||
|
||||
typedef typename boost::make_unsigned<T>::type U;
|
||||
|
||||
x = 0;
|
||||
|
||||
for( std::size_t i = 0; i < sizeof( x ); ++i )
|
||||
{
|
||||
x += static_cast<U>( test_value_bytes[ i ] ) << ( 8 * ( sizeof( x ) - i - 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void test()
|
||||
@ -137,13 +98,16 @@ namespace
|
||||
|
||||
// validate the values used by the tests below
|
||||
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
BOOST_TEST_EQ(native, big);
|
||||
BOOST_TEST_EQ(be::detail::std_endian_reverse(native), little);
|
||||
# else
|
||||
BOOST_TEST_EQ(be::detail::std_endian_reverse(native), big);
|
||||
BOOST_TEST_EQ(native, little);
|
||||
# endif
|
||||
if( be::order::native == be::order::big )
|
||||
{
|
||||
BOOST_TEST_EQ(native, big);
|
||||
BOOST_TEST_EQ(::std_endian_reverse(native), little);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_TEST_EQ(::std_endian_reverse(native), big);
|
||||
BOOST_TEST_EQ(native, little);
|
||||
}
|
||||
|
||||
// value-by-value tests
|
||||
|
||||
@ -247,16 +211,16 @@ namespace
|
||||
be::conditional_reverse_inplace(x, be::order::big, be::order::native);
|
||||
BOOST_TEST_EQ(x, native);
|
||||
x = little;
|
||||
be::conditional_reverse_inplace(x, be::order::little, be::order::big);
|
||||
be::conditional_reverse_inplace(x, be::order::little, be::order::big);
|
||||
BOOST_TEST_EQ(x, big);
|
||||
x = little;
|
||||
be::conditional_reverse_inplace(x, be::order::little, be::order::native);
|
||||
be::conditional_reverse_inplace(x, be::order::little, be::order::native);
|
||||
BOOST_TEST_EQ(x, native);
|
||||
x = native;
|
||||
be::conditional_reverse_inplace(x, be::order::native, be::order::big);
|
||||
be::conditional_reverse_inplace(x, be::order::native, be::order::big);
|
||||
BOOST_TEST_EQ(x, big);
|
||||
x = native;
|
||||
be::conditional_reverse_inplace(x, be::order::native, be::order::little);
|
||||
be::conditional_reverse_inplace(x, be::order::native, be::order::little);
|
||||
BOOST_TEST_EQ(x, little);
|
||||
|
||||
}
|
||||
@ -307,8 +271,8 @@ namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// User-defined types
|
||||
|
||||
// User-defined types
|
||||
|
||||
namespace user
|
||||
{
|
||||
// UDT1 supplies both endian_reverse and endian_reverse_inplace
|
||||
@ -367,8 +331,21 @@ namespace
|
||||
|
||||
int cpp_main(int, char * [])
|
||||
{
|
||||
if( be::order::native == be::order::little )
|
||||
{
|
||||
cout << "Little endian" << endl;
|
||||
}
|
||||
else if( be::order::native == be::order::big )
|
||||
{
|
||||
cout << "Big endian" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unknown endian" << endl;
|
||||
}
|
||||
|
||||
cout << "byte swap intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG << endl;
|
||||
|
||||
|
||||
//std::cerr << std::hex;
|
||||
|
||||
cout << "int8_t" << endl;
|
||||
@ -391,11 +368,6 @@ int cpp_main(int, char * [])
|
||||
cout << "uint64_t" << endl;
|
||||
test<uint64_t>();
|
||||
|
||||
cout << "float" << endl;
|
||||
test<float>();
|
||||
cout << "double" << endl;
|
||||
test<double>();
|
||||
|
||||
cout << "UDT 1" << endl;
|
||||
udt_test<user::UDT1>();
|
||||
|
||||
@ -410,4 +382,17 @@ int cpp_main(int, char * [])
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main( argc, argv );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
BOOST_ERROR( x.what() );
|
||||
return boost::report_errors();
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/endian/detail/disable_warnings_pop.hpp>
|
||||
|
95
test/data_test.cpp
Normal file
95
test/data_test.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class U> void test()
|
||||
{
|
||||
{
|
||||
U u( 0 );
|
||||
|
||||
unsigned char * p1 = u.data();
|
||||
void * p2 = &u;
|
||||
|
||||
BOOST_TEST_EQ( p1, p2 );
|
||||
}
|
||||
|
||||
{
|
||||
U const u( 0 );
|
||||
|
||||
unsigned char const * p1 = u.data();
|
||||
void const * p2 = &u;
|
||||
|
||||
BOOST_TEST_EQ( p1, p2 );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, std::size_t Bits> void test_unaligned()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
test< endian_buffer<order::big, T, Bits, align::no> >();
|
||||
test< endian_buffer<order::little, T, Bits, align::no> >();
|
||||
test< endian_buffer<order::native, T, Bits, align::no> >();
|
||||
|
||||
test< endian_arithmetic<order::big, T, Bits, align::no> >();
|
||||
test< endian_arithmetic<order::little, T, Bits, align::no> >();
|
||||
test< endian_arithmetic<order::native, T, Bits, align::no> >();
|
||||
}
|
||||
|
||||
template<class T, std::size_t Bits> void test_aligned()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
test< endian_buffer<order::big, T, Bits, align::yes> >();
|
||||
test< endian_buffer<order::little, T, Bits, align::yes> >();
|
||||
|
||||
test< endian_arithmetic<order::big, T, Bits, align::yes> >();
|
||||
test< endian_arithmetic<order::little, T, Bits, align::yes> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_unaligned<boost::int_least8_t, 8>();
|
||||
test_unaligned<boost::int_least16_t, 16>();
|
||||
test_unaligned<boost::int_least32_t, 24>();
|
||||
test_unaligned<boost::int_least32_t, 32>();
|
||||
test_unaligned<boost::int_least64_t, 40>();
|
||||
test_unaligned<boost::int_least64_t, 48>();
|
||||
test_unaligned<boost::int_least64_t, 56>();
|
||||
test_unaligned<boost::int_least64_t, 64>();
|
||||
|
||||
test_unaligned<boost::uint_least8_t, 8>();
|
||||
test_unaligned<boost::uint_least16_t, 16>();
|
||||
test_unaligned<boost::uint_least32_t, 24>();
|
||||
test_unaligned<boost::uint_least32_t, 32>();
|
||||
test_unaligned<boost::uint_least64_t, 40>();
|
||||
test_unaligned<boost::uint_least64_t, 48>();
|
||||
test_unaligned<boost::uint_least64_t, 56>();
|
||||
test_unaligned<boost::uint_least64_t, 64>();
|
||||
|
||||
test_unaligned<float, 32>();
|
||||
test_unaligned<double, 64>();
|
||||
|
||||
test_aligned<boost::int8_t, 8>();
|
||||
test_aligned<boost::int16_t, 16>();
|
||||
test_aligned<boost::int32_t, 32>();
|
||||
test_aligned<boost::int64_t, 64>();
|
||||
|
||||
test_aligned<boost::uint8_t, 8>();
|
||||
test_aligned<boost::uint16_t, 16>();
|
||||
test_aligned<boost::uint32_t, 32>();
|
||||
test_aligned<boost::uint64_t, 64>();
|
||||
|
||||
test_aligned<float, 32>();
|
||||
test_aligned<double, 64>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
196
test/deprecated_test.cpp
Normal file
196
test/deprecated_test.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
// deprecated_test.cpp ---------------------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2014, 2015
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// See library home page at http://www.boost.org/libs/endian
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#define BOOST_ENDIAN_DEPRECATED_NAMES
|
||||
#include <boost/endian/endian.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace boost::endian;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// check_size ----------------------------------------------------------------------//
|
||||
|
||||
void check_size()
|
||||
{
|
||||
BOOST_TEST_EQ(sizeof(big8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(big16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(big24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(big32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(big40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(big48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(big56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(big64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(ubig8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(ubig16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(ubig24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(ubig32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(ubig40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(ubig48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(ubig56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(ubig64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(little8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(little16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(little24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(little32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(little40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(little48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(little56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(little64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(ulittle8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(ulittle16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(ulittle24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(ulittle32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(ulittle40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(ulittle48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(ulittle56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(ulittle64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(native8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(native16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(native24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(native32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(native40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(native48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(native56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(native64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(unative8_t), 1);
|
||||
BOOST_TEST_EQ(sizeof(unative16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(unative24_t), 3);
|
||||
BOOST_TEST_EQ(sizeof(unative32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(unative40_t), 5);
|
||||
BOOST_TEST_EQ(sizeof(unative48_t), 6);
|
||||
BOOST_TEST_EQ(sizeof(unative56_t), 7);
|
||||
BOOST_TEST_EQ(sizeof(unative64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(aligned_big16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(aligned_big32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(aligned_big64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(aligned_ubig16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(aligned_ubig32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(aligned_ubig64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(aligned_little16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(aligned_little32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(aligned_little64_t), 8);
|
||||
|
||||
BOOST_TEST_EQ(sizeof(aligned_ulittle16_t), 2);
|
||||
BOOST_TEST_EQ(sizeof(aligned_ulittle32_t), 4);
|
||||
BOOST_TEST_EQ(sizeof(aligned_ulittle64_t), 8);
|
||||
|
||||
# ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
|
||||
BOOST_TEST_EQ(sizeof(endian<endianness::big, int_least16_t, 16>), 2);
|
||||
BOOST_TEST_EQ(sizeof(endian<endianness::big,
|
||||
int_least16_t, 16, alignment::unaligned>), 2);
|
||||
# endif
|
||||
} // check_size
|
||||
|
||||
// test_inserter_and_extractor -----------------------------------------------------//
|
||||
|
||||
void test_inserter_and_extractor()
|
||||
{
|
||||
std::cout << "test inserter and extractor..." << std::endl;
|
||||
|
||||
ubig64_t bu64(0x010203040506070ULL);
|
||||
ulittle64_t lu64(0x010203040506070ULL);
|
||||
|
||||
boost::uint64_t x;
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << bu64;
|
||||
ss >> x;
|
||||
BOOST_TEST_EQ(x, 0x010203040506070ULL);
|
||||
|
||||
ss.clear();
|
||||
ss << lu64;
|
||||
ss >> x;
|
||||
BOOST_TEST_EQ(x, 0x010203040506070ULL);
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
ubig64_t bu64z(0);
|
||||
ss >> bu64z;
|
||||
BOOST_TEST_EQ(bu64z, bu64);
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
ulittle64_t lu64z(0);
|
||||
ss >> lu64z;
|
||||
BOOST_TEST_EQ(lu64z, lu64);
|
||||
|
||||
std::cout << "test inserter and extractor complete" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
int cpp_main(int, char *[])
|
||||
{
|
||||
cout << "byte swap intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG << endl;
|
||||
|
||||
cout << " construct big endian aligned" << endl;
|
||||
big32_t x(1122334455);
|
||||
|
||||
cout << " assign to buffer from built-in integer" << endl;
|
||||
x = 1234567890;
|
||||
|
||||
cout << " operator==(buffer.value(), built-in)" << endl;
|
||||
bool b1(x == 1234567890);
|
||||
BOOST_TEST(b1);
|
||||
|
||||
cout << " construct little endian unaligned" << endl;
|
||||
little32_t x2(1122334455);
|
||||
|
||||
cout << " assign to buffer from built-in integer" << endl;
|
||||
x2 = 1234567890;
|
||||
|
||||
cout << " operator==(buffer.value(), built-in)" << endl;
|
||||
bool b2(x2 == 1234567890);
|
||||
BOOST_TEST(b2);
|
||||
|
||||
check_size();
|
||||
test_inserter_and_extractor();
|
||||
|
||||
cout << " done" << endl;
|
||||
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main( argc, argv );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
BOOST_ERROR( x.what() );
|
||||
return boost::report_errors();
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/endian/detail/disable_warnings_pop.hpp>
|
164
test/endian_arithmetic_test.cpp
Normal file
164
test/endian_arithmetic_test.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<BOOST_SCOPED_ENUM(boost::endian::order) Order, BOOST_SCOPED_ENUM(boost::endian::align) Align, class T> void test_arithmetic_( T const& x )
|
||||
{
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x );
|
||||
|
||||
BOOST_TEST_EQ( +x, +y );
|
||||
|
||||
BOOST_TEST_EQ( x + x, y + y );
|
||||
BOOST_TEST_EQ( x - x, y - y );
|
||||
|
||||
BOOST_TEST_EQ( x * x, y * y );
|
||||
BOOST_TEST_EQ( x / x, y / y );
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 += x, y2 += y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 -= x, y2 -= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 *= x, y2 *= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 /= x, y2 /= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( ++x2, ++y2 );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( --x2, --y2 );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2++, y2++ );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2--, y2-- );
|
||||
}
|
||||
}
|
||||
|
||||
template<BOOST_SCOPED_ENUM(boost::endian::order) Order, BOOST_SCOPED_ENUM(boost::endian::align) Align, class T> void test_integral_( T const& x )
|
||||
{
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x );
|
||||
|
||||
BOOST_TEST_EQ( x % x, y % y );
|
||||
|
||||
BOOST_TEST_EQ( x & x, y & y );
|
||||
BOOST_TEST_EQ( x | x, y | y );
|
||||
BOOST_TEST_EQ( x ^ x, y ^ y );
|
||||
|
||||
BOOST_TEST_EQ( x << 1, y << 1 );
|
||||
BOOST_TEST_EQ( x >> 1, y >> 1 );
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 %= x, y2 %= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 &= x, y2 &= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 |= x, y2 |= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 ^= x, y2 ^= y );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 <<= 1, y2 <<= 1 );
|
||||
}
|
||||
|
||||
{
|
||||
T x2( x );
|
||||
boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );
|
||||
|
||||
BOOST_TEST_EQ( x2 >>= 1, y2 >>= 1 );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_arithmetic( T const& x )
|
||||
{
|
||||
test_arithmetic_<boost::endian::order::little, boost::endian::align::no>( x );
|
||||
test_arithmetic_<boost::endian::order::little, boost::endian::align::yes>( x );
|
||||
test_arithmetic_<boost::endian::order::big, boost::endian::align::no>( x );
|
||||
test_arithmetic_<boost::endian::order::big, boost::endian::align::yes>( x );
|
||||
}
|
||||
|
||||
template<class T> void test_integral( T const& x )
|
||||
{
|
||||
test_arithmetic( x );
|
||||
|
||||
test_integral_<boost::endian::order::little, boost::endian::align::no>( x );
|
||||
test_integral_<boost::endian::order::little, boost::endian::align::yes>( x );
|
||||
test_integral_<boost::endian::order::big, boost::endian::align::no>( x );
|
||||
test_integral_<boost::endian::order::big, boost::endian::align::yes>( x );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_integral( 0x7EF2 );
|
||||
test_integral( 0x01020304u );
|
||||
|
||||
test_arithmetic( 3.1416f );
|
||||
test_arithmetic( 3.14159 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
59
test/endian_hpp_test.cpp
Normal file
59
test/endian_hpp_test.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
// conversion
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( endian_reverse( 0x01020304 ), 0x04030201 );
|
||||
}
|
||||
|
||||
// buffers
|
||||
|
||||
{
|
||||
little_uint32_buf_t v( 0x01020304 );
|
||||
|
||||
BOOST_TEST_EQ( v.data()[ 0 ], 0x04 );
|
||||
BOOST_TEST_EQ( v.data()[ 1 ], 0x03 );
|
||||
BOOST_TEST_EQ( v.data()[ 2 ], 0x02 );
|
||||
BOOST_TEST_EQ( v.data()[ 3 ], 0x01 );
|
||||
}
|
||||
|
||||
{
|
||||
big_uint32_buf_t v( 0x01020304 );
|
||||
|
||||
BOOST_TEST_EQ( v.data()[ 0 ], 0x01 );
|
||||
BOOST_TEST_EQ( v.data()[ 1 ], 0x02 );
|
||||
BOOST_TEST_EQ( v.data()[ 2 ], 0x03 );
|
||||
BOOST_TEST_EQ( v.data()[ 3 ], 0x04 );
|
||||
}
|
||||
|
||||
// arithmetic
|
||||
|
||||
{
|
||||
little_uint32_t v( 0x01020304 );
|
||||
|
||||
BOOST_TEST_EQ( v.data()[ 0 ], 0x04 );
|
||||
BOOST_TEST_EQ( v.data()[ 1 ], 0x03 );
|
||||
BOOST_TEST_EQ( v.data()[ 2 ], 0x02 );
|
||||
BOOST_TEST_EQ( v.data()[ 3 ], 0x01 );
|
||||
}
|
||||
|
||||
{
|
||||
big_uint32_t v( 0x01020304 );
|
||||
|
||||
BOOST_TEST_EQ( v.data()[ 0 ], 0x01 );
|
||||
BOOST_TEST_EQ( v.data()[ 1 ], 0x02 );
|
||||
BOOST_TEST_EQ( v.data()[ 2 ], 0x03 );
|
||||
BOOST_TEST_EQ( v.data()[ 3 ], 0x04 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -14,73 +14,68 @@
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <cassert>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
union U
|
||||
{
|
||||
big_int8_ut big_8;
|
||||
big_int16_ut big_16;
|
||||
big_int24_ut big_24;
|
||||
big_int32_ut big_32;
|
||||
big_int40_ut big_40;
|
||||
big_int48_ut big_48;
|
||||
big_int56_ut big_56;
|
||||
big_int64_ut big_64;
|
||||
|
||||
big_uint8_ut big_u8;
|
||||
big_uint16_ut big_u16;
|
||||
big_uint24_ut big_u24;
|
||||
big_uint32_ut big_u32;
|
||||
big_uint40_ut big_u40;
|
||||
big_uint48_ut big_u48;
|
||||
big_uint56_ut big_u56;
|
||||
big_uint64_ut big_u64;
|
||||
|
||||
little_int8_ut little_8;
|
||||
little_int16_ut little_16;
|
||||
little_int24_ut little_24;
|
||||
little_int32_ut little_32;
|
||||
little_int40_ut little_40;
|
||||
little_int48_ut little_48;
|
||||
little_int56_ut little_56;
|
||||
little_int64_ut little_64;
|
||||
|
||||
little_uint8_ut little_u8;
|
||||
little_uint16_ut little_u16;
|
||||
little_uint24_ut little_u24;
|
||||
little_uint32_ut little_u32;
|
||||
little_uint40_ut little_u40;
|
||||
little_uint48_ut little_u48;
|
||||
little_uint56_ut little_u56;
|
||||
little_uint64_ut little_u64;
|
||||
|
||||
native_int8_ut native_8;
|
||||
native_int16_ut native_16;
|
||||
native_int24_ut native_24;
|
||||
native_int32_ut native_32;
|
||||
native_int40_ut native_40;
|
||||
native_int48_ut native_48;
|
||||
native_int56_ut native_56;
|
||||
native_int64_ut native_64;
|
||||
|
||||
native_uint8_ut native_u8;
|
||||
native_uint16_ut native_u16;
|
||||
native_uint24_ut native_u24;
|
||||
native_uint32_ut native_u32;
|
||||
native_uint40_ut native_u40;
|
||||
native_uint48_ut native_u48;
|
||||
native_uint56_ut native_u56;
|
||||
native_uint64_ut native_u64;
|
||||
big_int8_t big_8;
|
||||
big_int16_t big_16;
|
||||
big_int24_t big_24;
|
||||
big_int32_t big_32;
|
||||
big_int40_t big_40;
|
||||
big_int48_t big_48;
|
||||
big_int56_t big_56;
|
||||
big_int64_t big_64;
|
||||
|
||||
big_uint8_t big_u8;
|
||||
big_uint16_t big_u16;
|
||||
big_uint24_t big_u24;
|
||||
big_uint32_t big_u32;
|
||||
big_uint40_t big_u40;
|
||||
big_uint48_t big_u48;
|
||||
big_uint56_t big_u56;
|
||||
big_uint64_t big_u64;
|
||||
|
||||
little_int8_t little_8;
|
||||
little_int16_t little_16;
|
||||
little_int24_t little_24;
|
||||
little_int32_t little_32;
|
||||
little_int40_t little_40;
|
||||
little_int48_t little_48;
|
||||
little_int56_t little_56;
|
||||
little_int64_t little_64;
|
||||
|
||||
little_uint8_t little_u8;
|
||||
little_uint16_t little_u16;
|
||||
little_uint24_t little_u24;
|
||||
little_uint32_t little_u32;
|
||||
little_uint40_t little_u40;
|
||||
little_uint48_t little_u48;
|
||||
little_uint56_t little_u56;
|
||||
little_uint64_t little_u64;
|
||||
|
||||
native_int8_t native_8;
|
||||
native_int16_t native_16;
|
||||
native_int24_t native_24;
|
||||
native_int32_t native_32;
|
||||
native_int40_t native_40;
|
||||
native_int48_t native_48;
|
||||
native_int56_t native_56;
|
||||
native_int64_t native_64;
|
||||
|
||||
native_uint8_t native_u8;
|
||||
native_uint16_t native_u16;
|
||||
native_uint24_t native_u24;
|
||||
native_uint32_t native_u32;
|
||||
native_uint40_t native_u40;
|
||||
native_uint48_t native_u48;
|
||||
native_uint56_t native_u56;
|
||||
native_uint64_t native_u64;
|
||||
};
|
||||
|
||||
U foo;
|
||||
|
||||
int cpp_main(int, char * [])
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
45
test/endian_ld_st_roundtrip_test.cpp
Normal file
45
test/endian_ld_st_roundtrip_test.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class T> void test( T const& x )
|
||||
{
|
||||
{
|
||||
unsigned char buffer[ sizeof(T) ];
|
||||
|
||||
boost::endian::endian_store<T, sizeof(T), boost::endian::order::little>( buffer, x );
|
||||
T x2 = boost::endian::endian_load<T, sizeof(T), boost::endian::order::little>( buffer );
|
||||
|
||||
BOOST_TEST_EQ( x, x2 );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char buffer[ sizeof(T) ];
|
||||
|
||||
boost::endian::endian_store<T, sizeof(T), boost::endian::order::big>( buffer, x );
|
||||
T x2 = boost::endian::endian_load<T, sizeof(T), boost::endian::order::big>( buffer );
|
||||
|
||||
BOOST_TEST_EQ( x, x2 );
|
||||
}
|
||||
}
|
||||
|
||||
enum E
|
||||
{
|
||||
e = 0xF1F2F3
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
test( 1.2e+34f );
|
||||
test( -1.234e+56 );
|
||||
test( e );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
263
test/endian_load_test.cpp
Normal file
263
test/endian_load_test.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
|
||||
// 1 -> 1
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int8_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint8_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int8_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint8_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
|
||||
// 1 -> 2
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
|
||||
// 2 -> 2
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
|
||||
// 1 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
|
||||
// 2 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
|
||||
// 3 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 3, boost::endian::order::little>( v )), 0x030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 3, boost::endian::order::little>( v )), 0x030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 3, boost::endian::order::big>( v )), 0x010203 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 3, boost::endian::order::big>( v )), 0x010203 );
|
||||
|
||||
// 4 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 4, boost::endian::order::little>( v )), 0x04030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 4, boost::endian::order::little>( v )), 0x04030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 4, boost::endian::order::big>( v )), 0x01020304 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 4, boost::endian::order::big>( v )), 0x01020304 );
|
||||
|
||||
// 1 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 1, boost::endian::order::little>( v )), 0x01 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 1, boost::endian::order::big>( v )), 0x01 );
|
||||
|
||||
// 2 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 2, boost::endian::order::little>( v )), 0x0201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 2, boost::endian::order::big>( v )), 0x0102 );
|
||||
|
||||
// 3 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 3, boost::endian::order::little>( v )), 0x030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 3, boost::endian::order::little>( v )), 0x030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 3, boost::endian::order::big>( v )), 0x010203 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 3, boost::endian::order::big>( v )), 0x010203 );
|
||||
|
||||
// 4 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 4, boost::endian::order::little>( v )), 0x04030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 4, boost::endian::order::little>( v )), 0x04030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 4, boost::endian::order::big>( v )), 0x01020304 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 4, boost::endian::order::big>( v )), 0x01020304 );
|
||||
|
||||
// 5 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 5, boost::endian::order::little>( v )), 0x0504030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 5, boost::endian::order::little>( v )), 0x0504030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 5, boost::endian::order::big>( v )), 0x0102030405 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 5, boost::endian::order::big>( v )), 0x0102030405 );
|
||||
|
||||
// 6 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 6, boost::endian::order::little>( v )), 0x060504030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 6, boost::endian::order::little>( v )), 0x060504030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 6, boost::endian::order::big>( v )), 0x010203040506 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 6, boost::endian::order::big>( v )), 0x010203040506 );
|
||||
|
||||
// 7 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 7, boost::endian::order::little>( v )), 0x07060504030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 7, boost::endian::order::little>( v )), 0x07060504030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 7, boost::endian::order::big>( v )), 0x01020304050607 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 7, boost::endian::order::big>( v )), 0x01020304050607 );
|
||||
|
||||
// 8 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 8, boost::endian::order::little>( v )), 0x0807060504030201 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 8, boost::endian::order::little>( v )), 0x0807060504030201 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 8, boost::endian::order::big>( v )), 0x0102030405060708 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 8, boost::endian::order::big>( v )), 0x0102030405060708 );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8 };
|
||||
|
||||
// 1 -> 1
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int8_t, 1, boost::endian::order::little>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint8_t, 1, boost::endian::order::little>( v )), 0xF1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int8_t, 1, boost::endian::order::big>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint8_t, 1, boost::endian::order::big>( v )), 0xF1 );
|
||||
|
||||
// 1 -> 2
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 1, boost::endian::order::little>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 1, boost::endian::order::little>( v )), 0xF1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 1, boost::endian::order::big>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 1, boost::endian::order::big>( v )), 0xF1 );
|
||||
|
||||
// 2 -> 2
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 2, boost::endian::order::little>( v )), -3343 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 2, boost::endian::order::little>( v )), 0xF2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int16_t, 2, boost::endian::order::big>( v )), -3598 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint16_t, 2, boost::endian::order::big>( v )), 0xF1F2 );
|
||||
|
||||
// 1 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 1, boost::endian::order::little>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 1, boost::endian::order::little>( v )), 0xF1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 1, boost::endian::order::big>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 1, boost::endian::order::big>( v )), 0xF1 );
|
||||
|
||||
// 2 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 2, boost::endian::order::little>( v )), -3343 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 2, boost::endian::order::little>( v )), 0xF2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 2, boost::endian::order::big>( v )), -3598 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 2, boost::endian::order::big>( v )), 0xF1F2 );
|
||||
|
||||
// 3 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 3, boost::endian::order::little>( v )), -789775 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 3, boost::endian::order::little>( v )), 0xF3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 3, boost::endian::order::big>( v )), -920845 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 3, boost::endian::order::big>( v )), 0xF1F2F3 );
|
||||
|
||||
// 4 -> 4
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 4, boost::endian::order::little>( v )), 0xF4F3F2F1 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 4, boost::endian::order::little>( v )), 0xF4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int32_t, 4, boost::endian::order::big>( v )), 0xF1F2F3F4 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint32_t, 4, boost::endian::order::big>( v )), 0xF1F2F3F4 );
|
||||
|
||||
// 1 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 1, boost::endian::order::little>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 1, boost::endian::order::little>( v )), 0xF1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 1, boost::endian::order::big>( v )), -15 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 1, boost::endian::order::big>( v )), 0xF1 );
|
||||
|
||||
// 2 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 2, boost::endian::order::little>( v )), -3343 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 2, boost::endian::order::little>( v )), 0xF2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 2, boost::endian::order::big>( v )), -3598 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 2, boost::endian::order::big>( v )), 0xF1F2 );
|
||||
|
||||
// 3 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 3, boost::endian::order::little>( v )), -789775 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 3, boost::endian::order::little>( v )), 0xF3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 3, boost::endian::order::big>( v )), -920845 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 3, boost::endian::order::big>( v )), 0xF1F2F3 );
|
||||
|
||||
// 4 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 4, boost::endian::order::little>( v )), -185339151 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 4, boost::endian::order::little>( v )), 0xF4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 4, boost::endian::order::big>( v )), -235736076 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 4, boost::endian::order::big>( v )), 0xF1F2F3F4 );
|
||||
|
||||
// 5 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 5, boost::endian::order::little>( v )), -43135012111 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 5, boost::endian::order::little>( v )), 0xF5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 5, boost::endian::order::big>( v )), -60348435211 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 5, boost::endian::order::big>( v )), 0xF1F2F3F4F5 );
|
||||
|
||||
// 6 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 6, boost::endian::order::little>( v )), -9938739662095 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 6, boost::endian::order::little>( v )), 0xF6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 6, boost::endian::order::big>( v )), -15449199413770 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 6, boost::endian::order::big>( v )), 0xF1F2F3F4F5F6 );
|
||||
|
||||
// 7 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 7, boost::endian::order::little>( v )), -2261738553347343 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 7, boost::endian::order::little>( v )), 0xF7F6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 7, boost::endian::order::big>( v )), -3954995049924873 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 7, boost::endian::order::big>( v )), 0xF1F2F3F4F5F6F7 );
|
||||
|
||||
// 8 -> 8
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 8, boost::endian::order::little>( v )), 0xF8F7F6F5F4F3F2F1 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 8, boost::endian::order::little>( v )), 0xF8F7F6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::int64_t, 8, boost::endian::order::big>( v )), 0xF1F2F3F4F5F6F7F8 );
|
||||
BOOST_TEST_EQ( (boost::endian::endian_load<boost::uint64_t, 8, boost::endian::order::big>( v )), 0xF1F2F3F4F5F6F7F8 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -12,40 +12,24 @@
|
||||
// This test probes operator overloading, including interaction between
|
||||
// operand types.
|
||||
|
||||
// See endian_test for tests of endianess correctness, size, and value.
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
//
|
||||
//
|
||||
// TODO: transition to BOOST_TEST; more testing can only help
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define BOOST_ENDIAN_LOG
|
||||
// See endian_test for tests of endianness correctness, size, and value.
|
||||
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4242 ) // conversion ..., possible loss of data
|
||||
# pragma warning( disable : 4244 ) // conversion ..., possible loss of data
|
||||
# pragma warning( disable : 4018 ) // signed/unsigned mismatch
|
||||
# pragma warning( disable : 4365 ) // signed/unsigned mismatch
|
||||
# pragma warning( disable : 4389 ) // signed/unsigned mismatch
|
||||
# pragma warning( disable : 4242 ) // conversion ..., possible loss of data
|
||||
# pragma warning( disable : 4244 ) // conversion ..., possible loss of data
|
||||
# pragma warning( disable : 4018 ) // signed/unsigned mismatch
|
||||
# pragma warning( disable : 4365 ) // signed/unsigned mismatch
|
||||
# pragma warning( disable : 4389 ) // signed/unsigned mismatch
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
#define BOOST_ENDIAN_LOG
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@ -69,9 +53,6 @@ template<> struct value_type<long> { typedef long type; };
|
||||
template<> struct value_type<unsigned long> { typedef unsigned long type; };
|
||||
template<> struct value_type<long long> { typedef long long type; };
|
||||
template<> struct value_type<unsigned long long> { typedef unsigned long long type; };
|
||||
template<> struct value_type<float> { typedef float type; };
|
||||
template<> struct value_type<double> { typedef double type; };
|
||||
template<> struct value_type<long double> { typedef long double type; };
|
||||
|
||||
template <class T1, class T2>
|
||||
struct default_construct
|
||||
@ -90,7 +71,7 @@ struct construct
|
||||
static void test()
|
||||
{
|
||||
T2 o2(1);
|
||||
T1 o1(o2); // TODO: does this make sense for char types?
|
||||
T1 o1(static_cast<T1>(o2));
|
||||
++o1; // quiet gcc unused variable warning
|
||||
}
|
||||
};
|
||||
@ -206,67 +187,67 @@ void op_test_aux()
|
||||
Test<T1, unsigned long>::test();
|
||||
Test<T1, long long>::test();
|
||||
Test<T1, unsigned long long>::test();
|
||||
Test<T1, be::big_int16_at>::test();
|
||||
Test<T1, be::big_int32_at>::test();
|
||||
Test<T1, be::big_int64_at>::test();
|
||||
Test<T1, be::big_uint16_at>::test();
|
||||
Test<T1, be::big_uint32_at>::test();
|
||||
Test<T1, be::big_uint64_at>::test();
|
||||
Test<T1, be::little_int16_at>::test();
|
||||
Test<T1, be::little_int32_at>::test();
|
||||
Test<T1, be::little_int64_at>::test();
|
||||
Test<T1, be::little_uint16_at>::test();
|
||||
Test<T1, be::little_uint32_at>::test();
|
||||
Test<T1, be::little_uint64_at>::test();
|
||||
Test<T1, be::big_int8_t>::test();
|
||||
Test<T1, be::big_int16_t>::test();
|
||||
Test<T1, be::big_int24_t>::test();
|
||||
Test<T1, be::big_int32_t>::test();
|
||||
Test<T1, be::big_int40_t>::test();
|
||||
Test<T1, be::big_int48_t>::test();
|
||||
Test<T1, be::big_int56_t>::test();
|
||||
Test<T1, be::big_int64_t>::test();
|
||||
Test<T1, be::big_uint8_t>::test();
|
||||
Test<T1, be::big_uint16_t>::test();
|
||||
Test<T1, be::big_uint24_t>::test();
|
||||
Test<T1, be::big_uint32_t>::test();
|
||||
Test<T1, be::big_uint40_t>::test();
|
||||
Test<T1, be::big_uint64_t>::test();
|
||||
Test<T1, be::little_int16_t>::test();
|
||||
Test<T1, be::little_int24_t>::test();
|
||||
Test<T1, be::little_int32_t>::test();
|
||||
Test<T1, be::little_int64_t>::test();
|
||||
Test<T1, be::little_uint16_t>::test();
|
||||
Test<T1, be::little_uint32_t>::test();
|
||||
Test<T1, be::little_uint56_t>::test();
|
||||
Test<T1, be::little_uint64_t>::test();
|
||||
Test<T1, be::big_int8_ut>::test();
|
||||
Test<T1, be::big_int16_ut>::test();
|
||||
Test<T1, be::big_int24_ut>::test();
|
||||
Test<T1, be::big_int32_ut>::test();
|
||||
Test<T1, be::big_int40_ut>::test();
|
||||
Test<T1, be::big_int48_ut>::test();
|
||||
Test<T1, be::big_int56_ut>::test();
|
||||
Test<T1, be::big_int64_ut>::test();
|
||||
Test<T1, be::big_uint8_ut>::test();
|
||||
Test<T1, be::big_uint16_ut>::test();
|
||||
Test<T1, be::big_uint24_ut>::test();
|
||||
Test<T1, be::big_uint32_ut>::test();
|
||||
Test<T1, be::big_uint40_ut>::test();
|
||||
Test<T1, be::big_uint64_ut>::test();
|
||||
Test<T1, be::little_int16_ut>::test();
|
||||
Test<T1, be::little_int24_ut>::test();
|
||||
Test<T1, be::little_int32_ut>::test();
|
||||
Test<T1, be::little_int64_ut>::test();
|
||||
Test<T1, be::little_uint16_ut>::test();
|
||||
Test<T1, be::little_uint32_ut>::test();
|
||||
Test<T1, be::little_uint56_ut>::test();
|
||||
Test<T1, be::little_uint64_ut>::test();
|
||||
Test<T1, be::native_int16_ut>::test();
|
||||
Test<T1, be::native_int24_ut>::test();
|
||||
Test<T1, be::native_int32_ut>::test();
|
||||
Test<T1, be::native_int64_ut>::test();
|
||||
Test<T1, be::native_int16_t>::test();
|
||||
Test<T1, be::native_int24_t>::test();
|
||||
Test<T1, be::native_int32_t>::test();
|
||||
Test<T1, be::native_int64_t>::test();
|
||||
#ifdef BOOST_LONG_ENDIAN_TEST
|
||||
Test<T1, be::native_uint16_ut>::test();
|
||||
Test<T1, be::native_uint24_ut>::test();
|
||||
Test<T1, be::native_uint32_ut>::test();
|
||||
Test<T1, be::native_uint48_ut>::test();
|
||||
Test<T1, be::native_uint64_ut>::test();
|
||||
Test<T1, be::big_uint48_ut>::test();
|
||||
Test<T1, be::big_uint56_ut>::test();
|
||||
Test<T1, be::little_int8_ut>::test();
|
||||
Test<T1, be::little_int56_ut>::test();
|
||||
Test<T1, be::little_int40_ut>::test();
|
||||
Test<T1, be::little_int48_ut>::test();
|
||||
Test<T1, be::little_uint8_ut>::test();
|
||||
Test<T1, be::little_uint24_ut>::test();
|
||||
Test<T1, be::little_uint40_ut>::test();
|
||||
Test<T1, be::little_uint48_ut>::test();
|
||||
Test<T1, be::native_int8_ut>::test();
|
||||
Test<T1, be::native_int40_ut>::test();
|
||||
Test<T1, be::native_int48_ut>::test();
|
||||
Test<T1, be::native_int56_ut>::test();
|
||||
Test<T1, be::native_uint8_ut>::test();
|
||||
Test<T1, be::native_uint40_ut>::test();
|
||||
Test<T1, be::native_uint56_ut>::test();
|
||||
Test<T1, be::native_uint16_t>::test();
|
||||
Test<T1, be::native_uint24_t>::test();
|
||||
Test<T1, be::native_uint32_t>::test();
|
||||
Test<T1, be::native_uint48_t>::test();
|
||||
Test<T1, be::native_uint64_t>::test();
|
||||
Test<T1, be::big_uint48_t>::test();
|
||||
Test<T1, be::big_uint56_t>::test();
|
||||
Test<T1, be::little_int8_t>::test();
|
||||
Test<T1, be::little_int56_t>::test();
|
||||
Test<T1, be::little_int40_t>::test();
|
||||
Test<T1, be::little_int48_t>::test();
|
||||
Test<T1, be::little_uint8_t>::test();
|
||||
Test<T1, be::little_uint24_t>::test();
|
||||
Test<T1, be::little_uint40_t>::test();
|
||||
Test<T1, be::little_uint48_t>::test();
|
||||
Test<T1, be::native_int8_t>::test();
|
||||
Test<T1, be::native_int40_t>::test();
|
||||
Test<T1, be::native_int48_t>::test();
|
||||
Test<T1, be::native_int56_t>::test();
|
||||
Test<T1, be::native_uint8_t>::test();
|
||||
Test<T1, be::native_uint40_t>::test();
|
||||
Test<T1, be::native_uint56_t>::test();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -284,61 +265,61 @@ void op_test()
|
||||
op_test_aux<Test, unsigned long>();
|
||||
op_test_aux<Test, long long>();
|
||||
op_test_aux<Test, unsigned long long>();
|
||||
op_test_aux<Test, be::big_int16_t>();
|
||||
op_test_aux<Test, be::big_int32_t>();
|
||||
op_test_aux<Test, be::big_int64_t>();
|
||||
op_test_aux<Test, be::little_int16_t>();
|
||||
op_test_aux<Test, be::little_int32_t>();
|
||||
op_test_aux<Test, be::little_int64_t>();
|
||||
op_test_aux<Test, be::big_int16_at>();
|
||||
op_test_aux<Test, be::big_int32_at>();
|
||||
op_test_aux<Test, be::big_int64_at>();
|
||||
op_test_aux<Test, be::little_int16_at>();
|
||||
op_test_aux<Test, be::little_int32_at>();
|
||||
op_test_aux<Test, be::little_int64_at>();
|
||||
#ifdef BOOST_LONG_ENDIAN_TEST
|
||||
op_test_aux<Test, be::big_int8_ut>();
|
||||
op_test_aux<Test, be::big_int16_ut>();
|
||||
op_test_aux<Test, be::big_int24_ut>();
|
||||
op_test_aux<Test, be::big_int32_ut>();
|
||||
op_test_aux<Test, be::big_int40_ut>();
|
||||
op_test_aux<Test, be::big_int48_ut>();
|
||||
op_test_aux<Test, be::big_int56_ut>();
|
||||
op_test_aux<Test, be::big_int64_ut>();
|
||||
op_test_aux<Test, be::big_uint8_ut>();
|
||||
op_test_aux<Test, be::big_uint16_ut>();
|
||||
op_test_aux<Test, be::big_uint24_ut>();
|
||||
op_test_aux<Test, be::big_uint32_ut>();
|
||||
op_test_aux<Test, be::big_uint40_ut>();
|
||||
op_test_aux<Test, be::big_uint48_ut>();
|
||||
op_test_aux<Test, be::big_uint56_ut>();
|
||||
op_test_aux<Test, be::big_uint64_ut>();
|
||||
op_test_aux<Test, be::little_int8_ut>();
|
||||
op_test_aux<Test, be::little_int16_ut>();
|
||||
op_test_aux<Test, be::little_int24_ut>();
|
||||
op_test_aux<Test, be::little_int32_ut>();
|
||||
op_test_aux<Test, be::little_int40_ut>();
|
||||
op_test_aux<Test, be::little_int48_ut>();
|
||||
op_test_aux<Test, be::little_int56_ut>();
|
||||
op_test_aux<Test, be::little_int64_ut>();
|
||||
op_test_aux<Test, be::little_uint8_ut>();
|
||||
op_test_aux<Test, be::little_uint16_ut>();
|
||||
op_test_aux<Test, be::little_uint24_ut>();
|
||||
op_test_aux<Test, be::little_uint32_ut>();
|
||||
op_test_aux<Test, be::little_uint40_ut>();
|
||||
op_test_aux<Test, be::little_uint48_ut>();
|
||||
op_test_aux<Test, be::little_uint56_ut>();
|
||||
op_test_aux<Test, be::little_uint64_ut>();
|
||||
op_test_aux<Test, be::native_int8_ut>();
|
||||
op_test_aux<Test, be::native_int16_ut>();
|
||||
op_test_aux<Test, be::native_int24_ut>();
|
||||
op_test_aux<Test, be::native_int32_ut>();
|
||||
op_test_aux<Test, be::native_int40_ut>();
|
||||
op_test_aux<Test, be::native_int48_ut>();
|
||||
op_test_aux<Test, be::native_int56_ut>();
|
||||
op_test_aux<Test, be::native_int64_ut>();
|
||||
op_test_aux<Test, be::native_uint8_ut>();
|
||||
op_test_aux<Test, be::native_uint16_ut>();
|
||||
op_test_aux<Test, be::native_uint24_ut>();
|
||||
op_test_aux<Test, be::native_uint32_ut>();
|
||||
op_test_aux<Test, be::native_uint40_ut>();
|
||||
op_test_aux<Test, be::native_uint48_ut>();
|
||||
op_test_aux<Test, be::native_uint56_ut>();
|
||||
op_test_aux<Test, be::native_uint64_ut>();
|
||||
op_test_aux<Test, be::big_int8_t>();
|
||||
op_test_aux<Test, be::big_int16_t>();
|
||||
op_test_aux<Test, be::big_int24_t>();
|
||||
op_test_aux<Test, be::big_int32_t>();
|
||||
op_test_aux<Test, be::big_int40_t>();
|
||||
op_test_aux<Test, be::big_int48_t>();
|
||||
op_test_aux<Test, be::big_int56_t>();
|
||||
op_test_aux<Test, be::big_int64_t>();
|
||||
op_test_aux<Test, be::big_uint8_t>();
|
||||
op_test_aux<Test, be::big_uint16_t>();
|
||||
op_test_aux<Test, be::big_uint24_t>();
|
||||
op_test_aux<Test, be::big_uint32_t>();
|
||||
op_test_aux<Test, be::big_uint40_t>();
|
||||
op_test_aux<Test, be::big_uint48_t>();
|
||||
op_test_aux<Test, be::big_uint56_t>();
|
||||
op_test_aux<Test, be::big_uint64_t>();
|
||||
op_test_aux<Test, be::little_int8_t>();
|
||||
op_test_aux<Test, be::little_int16_t>();
|
||||
op_test_aux<Test, be::little_int24_t>();
|
||||
op_test_aux<Test, be::little_int32_t>();
|
||||
op_test_aux<Test, be::little_int40_t>();
|
||||
op_test_aux<Test, be::little_int48_t>();
|
||||
op_test_aux<Test, be::little_int56_t>();
|
||||
op_test_aux<Test, be::little_int64_t>();
|
||||
op_test_aux<Test, be::little_uint8_t>();
|
||||
op_test_aux<Test, be::little_uint16_t>();
|
||||
op_test_aux<Test, be::little_uint24_t>();
|
||||
op_test_aux<Test, be::little_uint32_t>();
|
||||
op_test_aux<Test, be::little_uint40_t>();
|
||||
op_test_aux<Test, be::little_uint48_t>();
|
||||
op_test_aux<Test, be::little_uint56_t>();
|
||||
op_test_aux<Test, be::little_uint64_t>();
|
||||
op_test_aux<Test, be::native_int8_t>();
|
||||
op_test_aux<Test, be::native_int16_t>();
|
||||
op_test_aux<Test, be::native_int24_t>();
|
||||
op_test_aux<Test, be::native_int32_t>();
|
||||
op_test_aux<Test, be::native_int40_t>();
|
||||
op_test_aux<Test, be::native_int48_t>();
|
||||
op_test_aux<Test, be::native_int56_t>();
|
||||
op_test_aux<Test, be::native_int64_t>();
|
||||
op_test_aux<Test, be::native_uint8_t>();
|
||||
op_test_aux<Test, be::native_uint16_t>();
|
||||
op_test_aux<Test, be::native_uint24_t>();
|
||||
op_test_aux<Test, be::native_uint32_t>();
|
||||
op_test_aux<Test, be::native_uint40_t>();
|
||||
op_test_aux<Test, be::native_uint48_t>();
|
||||
op_test_aux<Test, be::native_uint56_t>();
|
||||
op_test_aux<Test, be::native_uint64_t>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -348,10 +329,10 @@ void test_inserter_and_extractor()
|
||||
{
|
||||
std::cout << "test inserter and extractor..." << std::endl;
|
||||
|
||||
be::big_uint64_ut bu64(0x010203040506070ULL);
|
||||
be::little_uint64_ut lu64(0x010203040506070ULL);
|
||||
be::big_uint64_t bu64(0x010203040506070ULL);
|
||||
be::little_uint64_t lu64(0x010203040506070ULL);
|
||||
|
||||
uint64_t x;
|
||||
boost::uint64_t x;
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
@ -366,13 +347,13 @@ void test_inserter_and_extractor()
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
be::big_uint64_ut bu64z(0);
|
||||
be::big_uint64_t bu64z(0);
|
||||
ss >> bu64z;
|
||||
BOOST_TEST_EQ(bu64z, bu64);
|
||||
|
||||
ss.clear();
|
||||
ss << 0x010203040506070ULL;
|
||||
be::little_uint64_ut lu64z(0);
|
||||
be::little_uint64_t lu64z(0);
|
||||
ss >> lu64z;
|
||||
BOOST_TEST_EQ(lu64z, lu64);
|
||||
|
||||
@ -380,34 +361,27 @@ void test_inserter_and_extractor()
|
||||
|
||||
}
|
||||
|
||||
void f_big_int32_ut(be::big_int32_ut) {}
|
||||
void f_big_int32_ut(be::big_int32_t) {}
|
||||
|
||||
// main ------------------------------------------------------------------------------//
|
||||
|
||||
int cpp_main(int, char * [])
|
||||
{
|
||||
be::endian_log = false;
|
||||
|
||||
// make sure some simple things work
|
||||
|
||||
be::big_int32_ut o1(1);
|
||||
be::big_int32_ut o2(2L);
|
||||
be::big_int32_ut o3(3LL);
|
||||
be::big_int64_ut o4(1);
|
||||
|
||||
// use cases; if BOOST_ENDIAN_LOG is defined, will output to clog info on
|
||||
// what overloads and conversions are actually being performed.
|
||||
|
||||
be::endian_log = true;
|
||||
be::big_int32_t o1(1);
|
||||
be::big_int32_t o2(2L);
|
||||
be::big_int32_t o3(3LL);
|
||||
be::big_int64_t o4(1);
|
||||
|
||||
std::clog << "set up test values\n";
|
||||
be::big_int32_ut big(12345);
|
||||
be::little_uint16_ut little_u(10);
|
||||
be::big_int64_ut result;
|
||||
be::big_int32_t big(12345);
|
||||
be::little_uint16_t little_u(10);
|
||||
be::big_int64_t result;
|
||||
|
||||
// this is the use case that is so irritating that it caused the endian
|
||||
// constructors to be made non-explicit
|
||||
std::clog << "\nf(1234) where f(big_int32_ut)\n";
|
||||
std::clog << "\nf(1234) where f(big_int32_t)\n";
|
||||
f_big_int32_ut(1234);
|
||||
|
||||
std::clog << "\nresult = big\n";
|
||||
@ -468,8 +442,8 @@ int cpp_main(int, char * [])
|
||||
// test from Roland Schwarz that detected ambiguities; these ambiguities
|
||||
// were eliminated by BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
|
||||
unsigned u;
|
||||
be::little_uint32_ut u1;
|
||||
be::little_uint32_ut u2;
|
||||
be::little_uint32_t u1;
|
||||
be::little_uint32_t u2;
|
||||
|
||||
u = 9;
|
||||
u1 = 1;
|
||||
@ -479,7 +453,7 @@ int cpp_main(int, char * [])
|
||||
|
||||
// variations to detect ambiguities
|
||||
|
||||
be::little_uint32_ut u3 = u1 + 5;
|
||||
be::little_uint32_t u3 = u1 + 5;
|
||||
u3 = u1 + 5u;
|
||||
|
||||
if (u1 == 5)
|
||||
@ -494,16 +468,14 @@ int cpp_main(int, char * [])
|
||||
u2 = u1 + 5u;
|
||||
|
||||
// one more wrinkle
|
||||
be::little_uint16_ut u4(3);
|
||||
be::little_uint16_t u4(3);
|
||||
u4 = 3;
|
||||
std::clog << "\nu2 = u1 + u4\n";
|
||||
u2 = u1 + u4;
|
||||
std::clog << "\n";
|
||||
|
||||
be::endian_log = false;
|
||||
|
||||
test_inserter_and_extractor();
|
||||
|
||||
|
||||
// perform the indicated test on ~60*60 operand types
|
||||
|
||||
op_test<default_construct>();
|
||||
@ -516,3 +488,16 @@ int cpp_main(int, char * [])
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main( argc, argv );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
BOOST_ERROR( x.what() );
|
||||
return boost::report_errors();
|
||||
}
|
||||
}
|
||||
|
40
test/endian_reverse_cx_test.cpp
Normal file
40
test/endian_reverse_cx_test.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||
|
||||
#elif defined(BOOST_ENDIAN_NO_INTRINSICS) && defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_ENDIAN_NO_INTRINSICS and BOOST_NO_CXX14_CONSTEXPR are defined")
|
||||
|
||||
#elif !defined(BOOST_ENDIAN_NO_INTRINSICS) && !defined(BOOST_ENDIAN_CONSTEXPR_INTRINSICS)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_ENDIAN_NO_INTRINSICS and BOOST_ENDIAN_CONSTEXPR_INTRINSICS are not defined")
|
||||
|
||||
#else
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
#define STATIC_ASSERT(expr) static_assert(expr, #expr)
|
||||
|
||||
STATIC_ASSERT( endian_reverse( static_cast<boost::uint8_t>( 0x01 ) ) == 0x01 );
|
||||
STATIC_ASSERT( endian_reverse( static_cast<boost::uint16_t>( 0x0102 ) ) == 0x0201 );
|
||||
STATIC_ASSERT( endian_reverse( static_cast<boost::uint32_t>( 0x01020304 ) ) == 0x04030201 );
|
||||
STATIC_ASSERT( endian_reverse( static_cast<boost::uint64_t>( 0x0102030405060708 ) ) == 0x0807060504030201 );
|
||||
|
||||
STATIC_ASSERT( big_to_native( native_to_big( 0x01020304 ) ) == 0x01020304 );
|
||||
STATIC_ASSERT( little_to_native( native_to_little( 0x01020304 ) ) == 0x01020304 );
|
||||
|
||||
STATIC_ASSERT( native_to_big( 0x01020304 ) == (conditional_reverse<order::native, order::big>( 0x01020304 )) );
|
||||
STATIC_ASSERT( native_to_big( 0x01020304 ) == conditional_reverse( 0x01020304, order::native, order::big ) );
|
||||
|
||||
#endif
|
223
test/endian_reverse_test.cpp
Normal file
223
test/endian_reverse_test.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4309 ) // static_cast: truncation of constant value
|
||||
#endif
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class T, std::size_t N = sizeof(T)> struct test_value
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct test_value<T, 1>
|
||||
{
|
||||
static const T v1 = static_cast<T>( 0x1F );
|
||||
static const T w1 = static_cast<T>( 0x1F );
|
||||
|
||||
static const T v2 = static_cast<T>( 0xF1 );
|
||||
static const T w2 = static_cast<T>( 0xF1 );
|
||||
};
|
||||
|
||||
template<class T> T const test_value<T, 1>::v1;
|
||||
template<class T> T const test_value<T, 1>::w1;
|
||||
template<class T> T const test_value<T, 1>::v2;
|
||||
template<class T> T const test_value<T, 1>::w2;
|
||||
|
||||
template<class T> struct test_value<T, 2>
|
||||
{
|
||||
static const T v1 = static_cast<T>( 0x1F2E );
|
||||
static const T w1 = static_cast<T>( 0x2E1F );
|
||||
|
||||
static const T v2 = static_cast<T>( 0xF1E2 );
|
||||
static const T w2 = static_cast<T>( 0xE2F1 );
|
||||
};
|
||||
|
||||
template<class T> T const test_value<T, 2>::v1;
|
||||
template<class T> T const test_value<T, 2>::w1;
|
||||
template<class T> T const test_value<T, 2>::v2;
|
||||
template<class T> T const test_value<T, 2>::w2;
|
||||
|
||||
template<class T> struct test_value<T, 4>
|
||||
{
|
||||
static const T v1 = static_cast<T>( 0x1F2E3D4C );
|
||||
static const T w1 = static_cast<T>( 0x4C3D2E1F );
|
||||
|
||||
static const T v2 = static_cast<T>( 0xF1E2D3C4 );
|
||||
static const T w2 = static_cast<T>( 0xC4D3E2F1 );
|
||||
};
|
||||
|
||||
template<class T> T const test_value<T, 4>::v1;
|
||||
template<class T> T const test_value<T, 4>::w1;
|
||||
template<class T> T const test_value<T, 4>::v2;
|
||||
template<class T> T const test_value<T, 4>::w2;
|
||||
|
||||
template<class T> struct test_value<T, 8>
|
||||
{
|
||||
static const T v1 = static_cast<T>( 0x1F2E3D4C5B6A7988ull );
|
||||
static const T w1 = static_cast<T>( 0x88796A5B4C3D2E1Full );
|
||||
|
||||
static const T v2 = static_cast<T>( 0xF1E2D3C4B5A69788ull );
|
||||
static const T w2 = static_cast<T>( 0x8897A6B5C4D3E2F1ull );
|
||||
};
|
||||
|
||||
template<class T> T const test_value<T, 8>::v1;
|
||||
template<class T> T const test_value<T, 8>::w1;
|
||||
template<class T> T const test_value<T, 8>::v2;
|
||||
template<class T> T const test_value<T, 8>::w2;
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
template<class T> struct test_value<T, 16>
|
||||
{
|
||||
static const T v1 = static_cast<T>( 0x1F2E3D4C5B6A7988ull ) << 64 | static_cast<T>( 0xF1E2D3C4B5A69780ull );
|
||||
static const T w1 = static_cast<T>( 0x8097A6B5C4D3E2F1ull ) << 64 | static_cast<T>( 0x88796A5B4C3D2E1Full );
|
||||
|
||||
static const T v2 = static_cast<T>( 0xF1E2D3C4B5A69788ull ) << 64 | static_cast<T>( 0x1F2E3D4C5B6A7980ull );
|
||||
static const T w2 = static_cast<T>( 0x80796A5B4C3D2E1Full ) << 64 | static_cast<T>( 0x8897A6B5C4D3E2F1ull );
|
||||
};
|
||||
|
||||
template<class T> T const test_value<T, 16>::v1;
|
||||
template<class T> T const test_value<T, 16>::w1;
|
||||
template<class T> T const test_value<T, 16>::v2;
|
||||
template<class T> T const test_value<T, 16>::w2;
|
||||
|
||||
#endif // #if defined(BOOST_HAS_INT128)
|
||||
|
||||
template<class T> void test()
|
||||
{
|
||||
using boost::endian::endian_reverse;
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
{
|
||||
T t1 = test_value<T>::v1;
|
||||
|
||||
T t2 = endian_reverse( t1 );
|
||||
BOOST_TEST_EQ( t2, test_value<T>::w1 );
|
||||
|
||||
T t3 = endian_reverse( t2 );
|
||||
BOOST_TEST_EQ( t3, t1 );
|
||||
|
||||
T t4 = t1;
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST_EQ( t4, test_value<T>::w1 );
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST_EQ( t4, t1 );
|
||||
}
|
||||
|
||||
{
|
||||
T t1 = test_value<T>::v2;
|
||||
|
||||
T t2 = endian_reverse( t1 );
|
||||
BOOST_TEST_EQ( t2, test_value<T>::w2 );
|
||||
|
||||
T t3 = endian_reverse( t2 );
|
||||
BOOST_TEST_EQ( t3, t1 );
|
||||
|
||||
T t4 = t1;
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST_EQ( t4, test_value<T>::w2 );
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST_EQ( t4, t1 );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_np()
|
||||
{
|
||||
using boost::endian::endian_reverse;
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
{
|
||||
T t1 = test_value<T>::v1;
|
||||
|
||||
T t2 = endian_reverse( t1 );
|
||||
BOOST_TEST( t2 == test_value<T>::w1 );
|
||||
|
||||
T t3 = endian_reverse( t2 );
|
||||
BOOST_TEST( t3 == t1 );
|
||||
|
||||
T t4 = t1;
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST( t4 == test_value<T>::w1 );
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST( t4 == t1 );
|
||||
}
|
||||
|
||||
{
|
||||
T t1 = test_value<T>::v2;
|
||||
|
||||
T t2 = endian_reverse( t1 );
|
||||
BOOST_TEST( t2 == test_value<T>::w2 );
|
||||
|
||||
T t3 = endian_reverse( t2 );
|
||||
BOOST_TEST( t3 == t1 );
|
||||
|
||||
T t4 = t1;
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST( t4 == test_value<T>::w2 );
|
||||
|
||||
endian_reverse_inplace( t4 );
|
||||
BOOST_TEST( t4 == t1 );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<boost::int8_t>();
|
||||
test<boost::uint8_t>();
|
||||
|
||||
test<boost::int16_t>();
|
||||
test<boost::uint16_t>();
|
||||
|
||||
test<boost::int32_t>();
|
||||
test<boost::uint32_t>();
|
||||
|
||||
test<boost::int64_t>();
|
||||
test<boost::uint64_t>();
|
||||
|
||||
test<char>();
|
||||
test<unsigned char>();
|
||||
test<signed char>();
|
||||
|
||||
test<short>();
|
||||
test<unsigned short>();
|
||||
|
||||
test<int>();
|
||||
test<unsigned int>();
|
||||
|
||||
test<long>();
|
||||
test<unsigned long>();
|
||||
|
||||
test<long long>();
|
||||
test<unsigned long long>();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
test<char16_t>();
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
test<char32_t>();
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
test_np<boost::int128_type>();
|
||||
test_np<boost::uint128_type>();
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
39
test/endian_reverse_test2.cpp
Normal file
39
test/endian_reverse_test2.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2019, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/type_traits/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace N
|
||||
{
|
||||
|
||||
struct X
|
||||
{
|
||||
boost::uint32_t m;
|
||||
};
|
||||
|
||||
template<class T> typename boost::enable_if_<boost::is_same<T, X>::value, T>::type endian_reverse( T x )
|
||||
{
|
||||
using boost::endian::endian_reverse;
|
||||
|
||||
X r = { endian_reverse( x.m ) };
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace N
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
N::X x1 = { 0x01020304 };
|
||||
N::X x2 = endian_reverse( x1 );
|
||||
|
||||
BOOST_TEST_EQ( x2.m, 0x04030201 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
83
test/endian_reverse_test3.cpp
Normal file
83
test/endian_reverse_test3.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class T> void test_reverse( T x )
|
||||
{
|
||||
using boost::endian::endian_reverse;
|
||||
|
||||
T x2( x );
|
||||
|
||||
x2 = endian_reverse( endian_reverse( x2 ) );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
x2 = boost::endian::native_to_little( boost::endian::little_to_native( x2 ) );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
x2 = boost::endian::native_to_big( boost::endian::big_to_native( x2 ) );
|
||||
BOOST_TEST( x == x2 );
|
||||
}
|
||||
|
||||
template<class T> void test_reverse_inplace( T x )
|
||||
{
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
T x2( x );
|
||||
|
||||
endian_reverse_inplace( x2 );
|
||||
endian_reverse_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
boost::endian::native_to_little_inplace( x2 );
|
||||
boost::endian::little_to_native_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
boost::endian::native_to_big_inplace( x2 );
|
||||
boost::endian::big_to_native_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
}
|
||||
|
||||
enum E1 { e1 };
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
enum E2: long { e2 };
|
||||
enum class E3 { e3 };
|
||||
enum class E4: long { e4 };
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
test_reverse( 1 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
test_reverse( E3::e3 );
|
||||
test_reverse( E4::e4 );
|
||||
|
||||
#endif
|
||||
|
||||
test_reverse_inplace( 1 );
|
||||
test_reverse_inplace( true );
|
||||
|
||||
test_reverse_inplace( 1.0f );
|
||||
test_reverse_inplace( 1.0 );
|
||||
|
||||
test_reverse_inplace( e1 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
test_reverse_inplace( e2 );
|
||||
test_reverse_inplace( E3::e3 );
|
||||
test_reverse_inplace( E4::e4 );
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
74
test/endian_reverse_test4.cpp
Normal file
74
test/endian_reverse_test4.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class T> void test_reverse_inplace( T x )
|
||||
{
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
T x2( x );
|
||||
|
||||
endian_reverse_inplace( x2 );
|
||||
endian_reverse_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
boost::endian::native_to_little_inplace( x2 );
|
||||
boost::endian::little_to_native_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
|
||||
boost::endian::native_to_big_inplace( x2 );
|
||||
boost::endian::big_to_native_inplace( x2 );
|
||||
BOOST_TEST( x == x2 );
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
int v1_;
|
||||
int v2_;
|
||||
};
|
||||
|
||||
inline bool operator==( X const& x1, X const& x2 )
|
||||
{
|
||||
return x1.v1_ == x2.v1_ && x1.v2_ == x2.v2_;
|
||||
}
|
||||
|
||||
inline void endian_reverse_inplace( X & x )
|
||||
{
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
endian_reverse_inplace( x.v1_ );
|
||||
endian_reverse_inplace( x.v2_ );
|
||||
}
|
||||
|
||||
struct Y
|
||||
{
|
||||
X x1_;
|
||||
X x2_[ 2 ];
|
||||
};
|
||||
|
||||
inline bool operator==( Y const& y1, Y const& y2 )
|
||||
{
|
||||
return y1.x1_ == y2.x1_ && y1.x2_[0] == y2.x2_[0] && y1.x2_[1] == y2.x2_[1];
|
||||
}
|
||||
|
||||
inline void endian_reverse_inplace( Y & y )
|
||||
{
|
||||
using boost::endian::endian_reverse_inplace;
|
||||
|
||||
endian_reverse_inplace( y.x1_ );
|
||||
endian_reverse_inplace( y.x2_ );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Y y = { { 1, 2 }, { { 3, 4 }, { 5, 6 } } };
|
||||
|
||||
test_reverse_inplace( y );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
30
test/endian_reverse_test5.cpp
Normal file
30
test/endian_reverse_test5.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
int v[] = { 1, 2 };
|
||||
|
||||
boost::endian::endian_reverse_inplace( v );
|
||||
boost::endian::endian_reverse_inplace( v );
|
||||
BOOST_TEST_EQ( v[0], 1 );
|
||||
BOOST_TEST_EQ( v[1], 2 );
|
||||
|
||||
boost::endian::native_to_little_inplace( v );
|
||||
boost::endian::little_to_native_inplace( v );
|
||||
BOOST_TEST_EQ( v[0], 1 );
|
||||
BOOST_TEST_EQ( v[1], 2 );
|
||||
|
||||
boost::endian::native_to_big_inplace( v );
|
||||
boost::endian::big_to_native_inplace( v );
|
||||
BOOST_TEST_EQ( v[0], 1 );
|
||||
BOOST_TEST_EQ( v[1], 2 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
310
test/endian_store_test.cpp
Normal file
310
test/endian_store_test.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
class byte_span
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned char const * p_;
|
||||
std::size_t n_;
|
||||
|
||||
public:
|
||||
|
||||
byte_span( unsigned char const * p, std::size_t n ): p_( p ), n_( n )
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t N> explicit byte_span( unsigned char const (&a)[ N ] ): p_( a ), n_( N )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==( byte_span const& r ) const
|
||||
{
|
||||
if( n_ != r.n_ ) return false;
|
||||
|
||||
for( std::size_t i = 0; i < n_; ++i )
|
||||
{
|
||||
if( p_[ i ] != r.p_[ i ] ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& os, byte_span s )
|
||||
{
|
||||
if( s.n_ == 0 ) return os;
|
||||
|
||||
os << std::hex << std::setfill( '0' ) << std::uppercase;
|
||||
|
||||
os << std::setw( 2 ) << +s.p_[ 0 ];
|
||||
|
||||
for( std::size_t i = 1; i < s.n_; ++i )
|
||||
{
|
||||
os << ':' << std::setw( 2 ) << +s.p_[ i ];
|
||||
}
|
||||
|
||||
os << std::dec << std::setfill( ' ' ) << std::nouppercase;;
|
||||
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> void test_1()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 1, boost::endian::order::little>( v, 0x01 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 1, boost::endian::order::big>( v, 0x01 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_2()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 2, boost::endian::order::little>( v, 0x0102 );
|
||||
|
||||
unsigned char w[] = { 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 2, boost::endian::order::big>( v, 0x0102 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_3()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 3, boost::endian::order::little>( v, 0x010203 );
|
||||
|
||||
unsigned char w[] = { 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 3, boost::endian::order::big>( v, 0x010203 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_4()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 4, boost::endian::order::little>( v, 0x01020304 );
|
||||
|
||||
unsigned char w[] = { 0x04, 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 4, boost::endian::order::big>( v, 0x01020304 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_5()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 5, boost::endian::order::little>( v, 0x0102030405 );
|
||||
|
||||
unsigned char w[] = { 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 5, boost::endian::order::big>( v, 0x0102030405 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_6()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 6, boost::endian::order::little>( v, 0x010203040506 );
|
||||
|
||||
unsigned char w[] = { 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 6, boost::endian::order::big>( v, 0x010203040506 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_7()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 7, boost::endian::order::little>( v, 0x01020304050607 );
|
||||
|
||||
unsigned char w[] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 7, boost::endian::order::big>( v, 0x01020304050607 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> void test_8()
|
||||
{
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 8, boost::endian::order::little>( v, 0x0102030405060708 );
|
||||
|
||||
unsigned char w[] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
|
||||
|
||||
boost::endian::endian_store<T, 8, boost::endian::order::big>( v, 0x0102030405060708 );
|
||||
|
||||
unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xAA };
|
||||
|
||||
BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 1
|
||||
|
||||
test_1<boost::int8_t>();
|
||||
test_1<boost::uint8_t>();
|
||||
|
||||
test_1<boost::int16_t>();
|
||||
test_1<boost::uint16_t>();
|
||||
|
||||
test_1<boost::int32_t>();
|
||||
test_1<boost::uint32_t>();
|
||||
|
||||
test_1<boost::int64_t>();
|
||||
test_1<boost::uint64_t>();
|
||||
|
||||
// 2
|
||||
|
||||
test_2<boost::int16_t>();
|
||||
test_2<boost::uint16_t>();
|
||||
|
||||
test_2<boost::int32_t>();
|
||||
test_2<boost::uint32_t>();
|
||||
|
||||
test_2<boost::int64_t>();
|
||||
test_2<boost::uint64_t>();
|
||||
|
||||
// 3
|
||||
|
||||
test_3<boost::int32_t>();
|
||||
test_3<boost::uint32_t>();
|
||||
|
||||
test_3<boost::int64_t>();
|
||||
test_3<boost::uint64_t>();
|
||||
|
||||
// 4
|
||||
|
||||
test_4<boost::int32_t>();
|
||||
test_4<boost::uint32_t>();
|
||||
|
||||
test_4<boost::int64_t>();
|
||||
test_4<boost::uint64_t>();
|
||||
|
||||
// 5
|
||||
|
||||
test_5<boost::int64_t>();
|
||||
test_5<boost::uint64_t>();
|
||||
|
||||
// 6
|
||||
|
||||
test_6<boost::int64_t>();
|
||||
test_6<boost::uint64_t>();
|
||||
|
||||
// 7
|
||||
|
||||
test_7<boost::int64_t>();
|
||||
test_7<boost::uint64_t>();
|
||||
|
||||
// 8
|
||||
|
||||
test_8<boost::int64_t>();
|
||||
test_8<boost::uint64_t>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
1074
test/endian_test.cpp
1074
test/endian_test.cpp
File diff suppressed because it is too large
Load Diff
83
test/float_typedef_test.cpp
Normal file
83
test/float_typedef_test.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
template<class T> struct align
|
||||
{
|
||||
char _;
|
||||
T v;
|
||||
|
||||
explicit align( typename T::value_type y ): _(), v( y )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct align2
|
||||
{
|
||||
char _;
|
||||
T v;
|
||||
};
|
||||
|
||||
template<class T, class U> void test_buffer( U const & y, bool aligned )
|
||||
{
|
||||
align<T> x( y );
|
||||
|
||||
BOOST_TEST_EQ( sizeof(x), aligned? sizeof( align2<U> ): 1 + sizeof(U) );
|
||||
|
||||
BOOST_TEST_EQ( x.v.value(), y );
|
||||
}
|
||||
|
||||
template<class T, class U> void test_arithmetic( U const & y, bool aligned )
|
||||
{
|
||||
test_buffer<T>( y, aligned );
|
||||
|
||||
align<T> x( y );
|
||||
|
||||
BOOST_TEST_EQ( x.v + 7, y + 7 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
// buffers
|
||||
|
||||
test_buffer<big_float32_buf_t>( 3.1416f, false );
|
||||
test_buffer<big_float64_buf_t>( 3.14159, false );
|
||||
|
||||
test_buffer<little_float32_buf_t>( 3.1416f, false );
|
||||
test_buffer<little_float64_buf_t>( 3.14159, false );
|
||||
|
||||
test_buffer<native_float32_buf_t>( 3.1416f, false );
|
||||
test_buffer<native_float64_buf_t>( 3.14159, false );
|
||||
|
||||
test_buffer<big_float32_buf_at>( 3.1416f, true );
|
||||
test_buffer<big_float64_buf_at>( 3.14159, true );
|
||||
|
||||
test_buffer<little_float32_buf_at>( 3.1416f, true );
|
||||
test_buffer<little_float64_buf_at>( 3.14159, true );
|
||||
|
||||
// arithmetic
|
||||
|
||||
test_arithmetic<big_float32_t>( 3.1416f, false );
|
||||
test_arithmetic<big_float64_t>( 3.14159, false );
|
||||
|
||||
test_arithmetic<little_float32_t>( 3.1416f, false );
|
||||
test_arithmetic<little_float64_t>( 3.14159, false );
|
||||
|
||||
test_arithmetic<native_float32_t>( 3.1416f, false );
|
||||
test_arithmetic<native_float64_t>( 3.14159, false );
|
||||
|
||||
test_arithmetic<big_float32_at>( 3.1416f, true );
|
||||
test_arithmetic<big_float64_at>( 3.14159, true );
|
||||
|
||||
test_arithmetic<little_float32_at>( 3.1416f, true );
|
||||
test_arithmetic<little_float64_at>( 3.14159, true );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,27 +1,35 @@
|
||||
// Copyright Beman Dawes 2013
|
||||
// Copyright 2018 Peter Dimov
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "test.hpp"
|
||||
#include <iostream>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/endian/detail/intrinsic.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "BOOST_ENDIAN_INTRINSIC_MSG: " BOOST_ENDIAN_INTRINSIC_MSG << std::endl;
|
||||
std::cout << "BOOST_ENDIAN_INTRINSIC_MSG: " BOOST_ENDIAN_INTRINSIC_MSG << std::endl;
|
||||
|
||||
#ifndef BOOST_ENDIAN_NO_INTRINSICS
|
||||
uint16_t x2 = 0x1122U;
|
||||
BOOST_ASSERT(BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x2) == 0x2211U);
|
||||
uint32_t x4 = 0x11223344UL;
|
||||
BOOST_ASSERT(BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x4) == 0x44332211UL);
|
||||
uint64_t x8 = 0x1122334455667788U;
|
||||
BOOST_ASSERT(BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x8) == 0x8877665544332211ULL);
|
||||
|
||||
uint16 x2 = 0x1122U;
|
||||
uint16 y2 = BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x2);
|
||||
BOOST_TEST_EQ( y2, 0x2211U );
|
||||
|
||||
uint32 x4 = 0x11223344UL;
|
||||
uint32 y4 = BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x4);
|
||||
BOOST_TEST_EQ( y4, 0x44332211UL );
|
||||
|
||||
uint64 x8 = 0x1122334455667788ULL;
|
||||
uint64 y8 = BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x8);
|
||||
BOOST_TEST_EQ( y8, 0x8877665544332211ULL );
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
78
test/is_scoped_enum_test.cpp
Normal file
78
test/is_scoped_enum_test.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/detail/is_scoped_enum.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
enum E1 {};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
enum E2: long {};
|
||||
enum class E3 {};
|
||||
enum class E4: long {};
|
||||
|
||||
#endif
|
||||
|
||||
struct X
|
||||
{
|
||||
operator int() const { return 0; }
|
||||
};
|
||||
|
||||
struct Y;
|
||||
|
||||
template<class T> void test_true()
|
||||
{
|
||||
using boost::endian::detail::is_scoped_enum;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((is_scoped_enum<T>));
|
||||
BOOST_TEST_TRAIT_TRUE((is_scoped_enum<T const>));
|
||||
BOOST_TEST_TRAIT_TRUE((is_scoped_enum<T volatile>));
|
||||
BOOST_TEST_TRAIT_TRUE((is_scoped_enum<T const volatile>));
|
||||
}
|
||||
|
||||
template<class T> void test_false()
|
||||
{
|
||||
using boost::endian::detail::is_scoped_enum;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((is_scoped_enum<T>));
|
||||
BOOST_TEST_TRAIT_FALSE((is_scoped_enum<T const>));
|
||||
BOOST_TEST_TRAIT_FALSE((is_scoped_enum<T volatile>));
|
||||
BOOST_TEST_TRAIT_FALSE((is_scoped_enum<T const volatile>));
|
||||
}
|
||||
|
||||
template<class T> void test_false_()
|
||||
{
|
||||
using boost::endian::detail::is_scoped_enum;
|
||||
|
||||
BOOST_TEST_NOT((is_scoped_enum<T>::value));
|
||||
BOOST_TEST_NOT((is_scoped_enum<T const>::value));
|
||||
BOOST_TEST_NOT((is_scoped_enum<T volatile>::value));
|
||||
BOOST_TEST_NOT((is_scoped_enum<T const volatile>::value));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_false<int>();
|
||||
test_false<bool>();
|
||||
test_false<X>();
|
||||
test_false_<Y>();
|
||||
test_false<void>();
|
||||
test_false<int[]>();
|
||||
test_false<int[1]>();
|
||||
|
||||
test_false<E1>();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
test_false<E2>();
|
||||
|
||||
test_true<E3>();
|
||||
test_true<E4>();
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
75
test/load_convenience_test.cpp
Normal file
75
test/load_convenience_test.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::endian;
|
||||
|
||||
unsigned char v[] = { 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8 };
|
||||
|
||||
// 16
|
||||
|
||||
BOOST_TEST_EQ( load_little_s16( v ), -3343 );
|
||||
BOOST_TEST_EQ( load_little_u16( v ), 0xF2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s16( v ), -3598 );
|
||||
BOOST_TEST_EQ( load_big_u16( v ), 0xF1F2 );
|
||||
|
||||
// 24
|
||||
|
||||
BOOST_TEST_EQ( load_little_s24( v ), -789775 );
|
||||
BOOST_TEST_EQ( load_little_u24( v ), 0xF3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s24( v ), -920845 );
|
||||
BOOST_TEST_EQ( load_big_u24( v ), 0xF1F2F3 );
|
||||
|
||||
// 32
|
||||
|
||||
BOOST_TEST_EQ( load_little_s32( v ), 0xF4F3F2F1 );
|
||||
BOOST_TEST_EQ( load_little_u32( v ), 0xF4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s32( v ), 0xF1F2F3F4 );
|
||||
BOOST_TEST_EQ( load_big_u32( v ), 0xF1F2F3F4 );
|
||||
|
||||
// 40
|
||||
|
||||
BOOST_TEST_EQ( load_little_s40( v ), -43135012111 );
|
||||
BOOST_TEST_EQ( load_little_u40( v ), 0xF5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s40( v ), -60348435211 );
|
||||
BOOST_TEST_EQ( load_big_u40( v ), 0xF1F2F3F4F5 );
|
||||
|
||||
// 48
|
||||
|
||||
BOOST_TEST_EQ( load_little_s48( v ), -9938739662095 );
|
||||
BOOST_TEST_EQ( load_little_u48( v ), 0xF6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s48( v ), -15449199413770 );
|
||||
BOOST_TEST_EQ( load_big_u48( v ), 0xF1F2F3F4F5F6 );
|
||||
|
||||
// 56
|
||||
|
||||
BOOST_TEST_EQ( load_little_s56( v ), -2261738553347343 );
|
||||
BOOST_TEST_EQ( load_little_u56( v ), 0xF7F6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s56( v ), -3954995049924873 );
|
||||
BOOST_TEST_EQ( load_big_u56( v ), 0xF1F2F3F4F5F6F7 );
|
||||
|
||||
// 64
|
||||
|
||||
BOOST_TEST_EQ( load_little_s64( v ), 0xF8F7F6F5F4F3F2F1 );
|
||||
BOOST_TEST_EQ( load_little_u64( v ), 0xF8F7F6F5F4F3F2F1 );
|
||||
|
||||
BOOST_TEST_EQ( load_big_s64( v ), 0xF1F2F3F4F5F6F7F8 );
|
||||
BOOST_TEST_EQ( load_big_u64( v ), 0xF1F2F3F4F5F6F7F8 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
//#define BOOST_ENDIAN_NO_INTRINSICS
|
||||
//#define BOOST_ENDIAN_LOG
|
||||
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
@ -18,8 +17,18 @@
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable : 4459)
|
||||
#endif
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::endian;
|
||||
|
||||
@ -33,6 +42,11 @@ namespace
|
||||
uint64_t n; // number of test cases to run
|
||||
int places = 2; // decimal places for times
|
||||
bool verbose (false);
|
||||
bool time_aligned (true);
|
||||
bool time_unaligned (true);
|
||||
bool time_16(true);
|
||||
bool time_32(true);
|
||||
bool time_64(true);
|
||||
|
||||
void process_command_line(int argc, char * argv[])
|
||||
{
|
||||
@ -47,17 +61,27 @@ namespace
|
||||
|
||||
if (argc >=2)
|
||||
#ifndef _MSC_VER
|
||||
n = std::atoll(argv[1]);
|
||||
n = atoll(argv[1]);
|
||||
#else
|
||||
n = _atoi64(argv[1]);
|
||||
#endif
|
||||
|
||||
for (; argc > 2; ++argv, --argc)
|
||||
for (; argc > 2; ++argv, --argc)
|
||||
{
|
||||
if ( *(argv[2]+1) == 'p' )
|
||||
places = atoi( argv[2]+2 );
|
||||
else if ( *(argv[2]+1) == 'v' )
|
||||
else if (*(argv[2] + 1) == 'v')
|
||||
verbose = true;
|
||||
else if (*(argv[2] + 1) == 'a')
|
||||
time_unaligned = false;
|
||||
else if (*(argv[2] + 1) == 'u')
|
||||
time_aligned = false;
|
||||
else if (*(argv[2] + 1) == '1')
|
||||
time_32 = time_64 = false;
|
||||
else if (*(argv[2] + 1) == '3')
|
||||
time_16 = time_64 = false;
|
||||
else if (*(argv[2] + 1) == '6')
|
||||
time_16 = time_32 = false;
|
||||
else
|
||||
{
|
||||
cout << "Error - unknown option: " << argv[2] << "\n\n";
|
||||
@ -66,24 +90,44 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
if (argc < 2)
|
||||
{
|
||||
cout << "Usage: loop_time_test n [Options]\n"
|
||||
" The argument n specifies the number of test cases to run\n"
|
||||
" Options:\n"
|
||||
" -v Verbose messages\n"
|
||||
" -p# Decimal places for times; default -p" << places << "\n";
|
||||
" -p# Decimal places for times; default -p" << places << "\n"
|
||||
" -a Aligned tests only\n"
|
||||
" -u Unaligned tests only\n"
|
||||
" -16 16-bit tests only\n"
|
||||
" -32 32-bit tests only\n"
|
||||
" -64 64-bit tests only\n"
|
||||
;
|
||||
return std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string with_digit_separator(int64_t x)
|
||||
{
|
||||
std::string s = boost::lexical_cast<std::string>(x);
|
||||
std::string s2;
|
||||
|
||||
for (std::string::size_type i = 0; i < s.size(); ++i)
|
||||
{
|
||||
if (i && ((s.size()-i) % 3) == 0)
|
||||
s2 += '\'';
|
||||
s2 += s[i];
|
||||
}
|
||||
return s2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <class T, class EndianT>
|
||||
void time()
|
||||
{
|
||||
T total = 0;
|
||||
{
|
||||
{
|
||||
// cout << "*************Endian integer approach...\n";
|
||||
EndianT x(0);
|
||||
boost::timer::cpu_timer t;
|
||||
@ -95,7 +139,7 @@ namespace
|
||||
total += x;
|
||||
cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>";
|
||||
}
|
||||
{
|
||||
{
|
||||
// cout << "***************Endian conversion approach...\n";
|
||||
T x(0);
|
||||
boost::timer::cpu_timer t;
|
||||
@ -113,88 +157,88 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_big_align_int16()
|
||||
{
|
||||
cout << "<tr><td>16-bit aligned big endian</td>";
|
||||
time<int16_t, big_int16_t>();
|
||||
time<int16_t, big_int16_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_align_int16()
|
||||
{
|
||||
cout << "<tr><td>16-bit aligned little endian</td>";
|
||||
time<int16_t, little_int16_t>();
|
||||
time<int16_t, little_int16_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_big_int16()
|
||||
{
|
||||
cout << "<tr><td>16-bit unaligned big endian</td>";
|
||||
time<int16_t, big_int16_ut>();
|
||||
time<int16_t, big_int16_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_int16()
|
||||
{
|
||||
cout << "<tr><td>16-bit unaligned little endian</td>";
|
||||
time<int16_t, little_int16_ut>();
|
||||
time<int16_t, little_int16_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
|
||||
void test_big_align_int32()
|
||||
{
|
||||
cout << "<tr><td>32-bit aligned big endian</td>";
|
||||
time<int32_t, big_int32_t>();
|
||||
time<int32_t, big_int32_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_align_int32()
|
||||
{
|
||||
cout << "<tr><td>32-bit aligned little endian</td>";
|
||||
time<int32_t, little_int32_t>();
|
||||
time<int32_t, little_int32_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_big_int32()
|
||||
{
|
||||
cout << "<tr><td>32-bit unaligned big endian</td>";
|
||||
time<int32_t, big_int32_ut>();
|
||||
time<int32_t, big_int32_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_int32()
|
||||
{
|
||||
cout << "<tr><td>32-bit unaligned little endian</td>";
|
||||
time<int32_t, little_int32_ut>();
|
||||
time<int32_t, little_int32_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
|
||||
void test_big_align_int64()
|
||||
{
|
||||
cout << "<tr><td>64-bit aligned big endian</td>";
|
||||
time<int64_t, big_int64_t>();
|
||||
time<int64_t, big_int64_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_align_int64()
|
||||
{
|
||||
cout << "<tr><td>64-bit aligned little endian</td>";
|
||||
time<int64_t, little_int64_t>();
|
||||
time<int64_t, little_int64_at>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_big_int64()
|
||||
{
|
||||
cout << "<tr><td>64-bit unaligned big endian</td>";
|
||||
time<int64_t, big_int64_ut>();
|
||||
time<int64_t, big_int64_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
void test_little_int64()
|
||||
{
|
||||
cout << "<tr><td>64-bit unaligned little endian</td>";
|
||||
time<int64_t, little_int64_ut>();
|
||||
time<int64_t, little_int64_t>();
|
||||
cout << "</tr>\n";
|
||||
}
|
||||
|
||||
@ -205,39 +249,65 @@ namespace
|
||||
int cpp_main(int argc, char* argv[])
|
||||
{
|
||||
process_command_line(argc, argv);
|
||||
|
||||
|
||||
cout
|
||||
<< "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n"
|
||||
<< "<!-- boost-no-inspect -->\n"
|
||||
<< "<div align=\"center\"> <center>\n"
|
||||
<< "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\""
|
||||
<< "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n"
|
||||
<< "<tr><td colspan=\"6\" align=\"center\"><b>"
|
||||
<< BOOST_COMPILER << "</b></td></tr>\n"
|
||||
<< "<tr><td colspan=\"6\" align=\"center\"><b>"
|
||||
<< " Iterations: " << n
|
||||
<< " Iterations: " << with_digit_separator(n)
|
||||
<< ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG
|
||||
<< "</b></td></tr>\n"
|
||||
<< "<tr><td><b>Test Case</b></td>\n"
|
||||
"<td align=\"center\"><b>Endian<br>type</b></td>\n"
|
||||
"<td align=\"center\"><b>Endian<br>arithmetic<br>type</b></td>\n"
|
||||
"<td align=\"center\"><b>Endian<br>conversion<br>function</b></td>\n"
|
||||
"</tr>\n"
|
||||
;
|
||||
|
||||
test_big_align_int16();
|
||||
test_little_align_int16();
|
||||
test_big_int16();
|
||||
test_little_int16();
|
||||
|
||||
test_big_align_int32();
|
||||
test_little_align_int32();
|
||||
test_big_int32();
|
||||
test_little_int32();
|
||||
if (time_aligned)
|
||||
{
|
||||
if (time_16)
|
||||
{
|
||||
test_big_align_int16();
|
||||
test_little_align_int16();
|
||||
}
|
||||
if (time_32)
|
||||
{
|
||||
test_big_align_int32();
|
||||
test_little_align_int32();
|
||||
}
|
||||
if (time_64)
|
||||
{
|
||||
test_big_align_int64();
|
||||
test_little_align_int64();
|
||||
}
|
||||
}
|
||||
|
||||
test_big_align_int64();
|
||||
test_little_align_int64();
|
||||
test_big_int64();
|
||||
test_little_int64();
|
||||
if (time_unaligned)
|
||||
{
|
||||
if (time_16)
|
||||
{
|
||||
test_big_int16();
|
||||
test_little_int16();
|
||||
}
|
||||
if (time_32)
|
||||
{
|
||||
test_big_int32();
|
||||
test_little_int32();
|
||||
}
|
||||
if (time_64)
|
||||
{
|
||||
test_big_int64();
|
||||
test_little_int64();
|
||||
}
|
||||
}
|
||||
|
||||
cout << "\n</table>\n</body>\n</html>\n";
|
||||
cout << "\n</div> </center>\n"
|
||||
<< "\n</table>\n</body>\n</html>\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,30 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D9C80FE0-20A6-4711-A3F4-676019BD5A06}</ProjectGuid>
|
||||
<RootNamespace>associatedfiles</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -34,9 +56,15 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@ -49,6 +77,16 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@ -63,6 +101,20 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\boost\endian\arithmetic.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\endian\buffers.hpp" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,33 +22,34 @@
|
||||
<ProjectGuid>{C9FEAE75-4DD9-44F5-B302-9910559A91BE}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>benchmark</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -77,6 +78,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
@ -85,6 +87,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -1,31 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>buffer_test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -36,18 +58,49 @@
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
@ -71,6 +124,26 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<PreprocessorDefinitions>BOOST_ALL_DYN_LINK;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>BOOST_LIGHTWEIGHT_TEST_OSTREAM=std::cout;BOOST_ALL_DYN_LINK;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Message>Executing test $(TargetName).exe...</Message>
|
||||
|
156
test/msvc/conversion_test_clang/conversion_test_clang.vcxproj
Normal file
156
test/msvc/conversion_test_clang/conversion_test_clang.vcxproj
Normal file
@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0DA4B909-1E3D-43A2-A248-3FE73E499726}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>conversion_test_clang</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<AdditionalIncludeDirectories>../../../../../</AdditionalIncludeDirectories>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>"$(TargetDir)\$(TargetName).exe"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\conversion_test.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,31 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{1139E765-DE0F-497A-A7D9-EB2683521DF1}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>conversion_use_case</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -36,17 +58,33 @@
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
@ -61,6 +99,20 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@ -79,6 +131,24 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\example\conversion_use_case.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -25,33 +25,34 @@
|
||||
<ProjectGuid>{EAE18F4D-AAF2-4C19-86FB-1144B5BD5993}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>converter_test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -80,6 +81,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
@ -88,6 +90,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
89
test/msvc/deprecated_test/deprecated_test.vcxproj
Normal file
89
test/msvc/deprecated_test/deprecated_test.vcxproj
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DA4BC67F-9284-4D2C-81D5-407312C31BD7}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>deprecated_test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\deprecated_test.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
28
test/msvc/endian-clang-c2.sln
Normal file
28
test/msvc/endian-clang-c2.sln
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_test_clang", "conversion_test_clang\conversion_test_clang.vcxproj", "{0DA4B909-1E3D-43A2-A248-3FE73E499726}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Debug|x64.Build.0 = Debug|x64
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Debug|x86.Build.0 = Debug|Win32
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Release|x64.ActiveCfg = Release|x64
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Release|x64.Build.0 = Release|x64
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0DA4B909-1E3D-43A2-A248-3FE73E499726}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22310.1
|
||||
VisualStudioVersion = 14.0.22609.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_test", "endian_test\endian_test.vcxproj", "{74C201F3-8308-40BE-BC0F-24974DEAF405}"
|
||||
EndProject
|
||||
@ -25,12 +25,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loop_time_test", "loop_time
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buffer_test", "buffer_test\buffer_test.vcxproj", "{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uses_cases", "uses_cases\uses_cases.vcxproj", "{36BF451A-EAEF-4140-92E4-6EA461A26107}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_use_case", "conversion_use_case\conversion_use_case.vcxproj", "{1139E765-DE0F-497A-A7D9-EB2683521DF1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "associated-files", "associated-files\associated-files.vcxproj", "{D9C80FE0-20A6-4711-A3F4-676019BD5A06}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "experiment", "experiment\experiment.vcxproj", "{CE9D8719-6E86-41D0-97CA-5BE5272594E9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deprecated_test", "deprecated_test\deprecated_test.vcxproj", "{DA4BC67F-9284-4D2C-81D5-407312C31BD7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@ -117,27 +119,40 @@ Global
|
||||
{541A2D06-B34E-4592-BE47-F87DF47E73D8}.Release|x64.Build.0 = Release|x64
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Debug|x64.Build.0 = Debug|x64
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|Win32.Build.0 = Release|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.ActiveCfg = Release|Win32
|
||||
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|Win32.Build.0 = Release|Win32
|
||||
{36BF451A-EAEF-4140-92E4-6EA461A26107}.Release|x64.ActiveCfg = Release|Win32
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.ActiveCfg = Release|x64
|
||||
{BFB68CF4-EB92-4E5C-9694-A939496C5CDE}.Release|x64.Build.0 = Release|x64
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Debug|x64.Build.0 = Debug|x64
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Release|Win32.Build.0 = Release|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Release|x64.ActiveCfg = Release|Win32
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Release|x64.ActiveCfg = Release|x64
|
||||
{1139E765-DE0F-497A-A7D9-EB2683521DF1}.Release|x64.Build.0 = Release|x64
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Debug|x64.Build.0 = Debug|x64
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|Win32.Build.0 = Release|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.ActiveCfg = Release|Win32
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.ActiveCfg = Release|x64
|
||||
{D9C80FE0-20A6-4711-A3F4-676019BD5A06}.Release|x64.Build.0 = Release|x64
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|Win32.Build.0 = Release|Win32
|
||||
{CE9D8719-6E86-41D0-97CA-5BE5272594E9}.Release|x64.ActiveCfg = Release|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Release|Win32.Build.0 = Release|Win32
|
||||
{DA4BC67F-9284-4D2C-81D5-407312C31BD7}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,29 +22,30 @@
|
||||
<ProjectGuid>{8638A3D8-D121-40BF-82E5-127F1B1B2CB2}</ProjectGuid>
|
||||
<RootNamespace>endian_example</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -77,6 +78,12 @@
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,29 +22,30 @@
|
||||
<ProjectGuid>{3926C6DC-9D1E-4227-BEF5-81F5EC621A75}</ProjectGuid>
|
||||
<RootNamespace>endian_in_union_test</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -79,7 +80,12 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,29 +22,30 @@
|
||||
<ProjectGuid>{A0060A5B-673C-4AD8-BD08-A5C643B1A1CB}</ProjectGuid>
|
||||
<RootNamespace>endian_operations_test</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -77,12 +78,16 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,29 +22,30 @@
|
||||
<ProjectGuid>{74C201F3-8308-40BE-BC0F-24974DEAF405}</ProjectGuid>
|
||||
<RootNamespace>endian_test</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -79,7 +80,12 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,31 +22,32 @@
|
||||
<ProjectGuid>{541A2D06-B34E-4592-BE47-F87DF47E73D8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>loop_time_test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -75,12 +76,14 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -95,7 +98,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>"$(TargetDir)\$(TargetName).exe" 1</Command>
|
||||
<Command>"$(TargetDir)\$(TargetName).exe" 1234</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -131,7 +134,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>"$(TargetDir)\$(TargetName).exe" 1000000000</Command>
|
||||
<Command>"$(TargetDir)\$(TargetName).exe" 100000000</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -143,6 +146,8 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||
<AssemblerListingLocation>c:/temp/</AssemblerListingLocation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@ -22,29 +22,30 @@
|
||||
<ProjectGuid>{8420E151-B23B-4651-B526-6AB11EF1E278}</ProjectGuid>
|
||||
<RootNamespace>scoped_enum_emulation_test</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@ -77,6 +78,12 @@
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExecutablePath>..\..\..\..\..\stage\lib;$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user