forked from boostorg/endian
Compare commits
90 Commits
feature/fl
...
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 |
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}
|
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
|
166
.travis.yml
166
.travis.yml
@ -1,12 +1,10 @@
|
||||
# Copyright 2016-2018 Peter Dimov
|
||||
# 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
|
||||
|
||||
sudo: false
|
||||
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
|
||||
branches:
|
||||
only:
|
||||
@ -26,7 +24,26 @@ matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
|
||||
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
|
||||
@ -128,20 +145,18 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
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++-9
|
||||
- g++-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
@ -150,6 +165,7 @@ matrix:
|
||||
- clang-3.3
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
@ -164,7 +180,6 @@ matrix:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
@ -175,7 +190,16 @@ matrix:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
- libstdc++-4.9-dev
|
||||
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
|
||||
|
||||
@ -186,7 +210,6 @@ matrix:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
@ -197,7 +220,6 @@ matrix:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
@ -210,7 +232,6 @@ matrix:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-5.0
|
||||
@ -221,7 +242,6 @@ matrix:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
@ -232,7 +252,6 @@ matrix:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
@ -243,7 +262,7 @@ matrix:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
- llvm-toolchain-xenial-7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
@ -254,10 +273,10 @@ matrix:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-8
|
||||
- llvm-toolchain-xenial-8
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
compiler: clang++-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
@ -266,29 +285,50 @@ matrix:
|
||||
- clang-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
dist: bionic
|
||||
compiler: clang++-10
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
- clang-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-8
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z VARIANT=release
|
||||
dist: bionic
|
||||
compiler: clang++-11
|
||||
env: TOOLSET=clang COMPILER=clang++-11 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
- 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:
|
||||
@ -296,23 +336,79 @@ matrix:
|
||||
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 UBSAN_OPTIONS=print_stacktrace=1
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64 UBSAN_OPTIONS=print_stacktrace=1
|
||||
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: CMAKE_SUBDIR_TEST=1
|
||||
env: CMAKE_TEST=1
|
||||
script:
|
||||
- cd libs/endian/test/cmake_subdir_test && mkdir __build__ && cd __build__
|
||||
- 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 ..
|
||||
@ -327,7 +423,7 @@ install:
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 -j3 libs/endian/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
|
||||
- ./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:
|
||||
|
@ -2,11 +2,11 @@
|
||||
# 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
|
||||
|
||||
# Partial (add_subdirectory only) and experimental CMake support
|
||||
# Subject to change; please do not rely on the contents of this file yet
|
||||
if(NOT DEFINED IDF_TARGET)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(BoostEndian LANGUAGES CXX)
|
||||
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)
|
||||
@ -14,10 +14,34 @@ 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::predef
|
||||
Boost::static_assert
|
||||
Boost::type_traits
|
||||
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()
|
||||
|
||||
|
29
README
29
README
@ -1,29 +0,0 @@
|
||||
Boost Endian library
|
||||
|
||||
The Endian library is included in Boost release 1.58.0 and later.
|
||||
|
||||
See http://boostorg.github.io/endian to browse the documentation without having to
|
||||
download the library or install Boost.
|
||||
|
||||
To experiment with the Endian library, various other boost libraries must be
|
||||
available. So you need to install Boost or clone a current version of boostorg/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 boost
|
||||
git pull
|
||||
git submodule update --init
|
||||
git submodule update
|
||||
./b2 headers
|
||||
|
||||
On Windows, "./" is unnecessary.
|
||||
|
||||
---------------------------
|
||||
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).
|
@ -16,6 +16,7 @@ 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
|
||||
|
@ -13,22 +13,18 @@ Beman Dawes
|
||||
: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/conversion.adoc[]
|
||||
|
||||
include::endian/buffers.adoc[]
|
||||
|
||||
include::endian/arithmetic.adoc[]
|
||||
|
||||
include::endian/choosing_approach.adoc[]
|
||||
|
||||
include::endian/mini_review_topics.adoc[]
|
||||
include::endian/conversion.adoc[]
|
||||
include::endian/buffers.adoc[]
|
||||
include::endian/arithmetic.adoc[]
|
||||
include::endian/history.adoc[]
|
||||
|
||||
:leveloffset: -1
|
||||
|
||||
|
@ -39,6 +39,7 @@ 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:
|
||||
|
||||
@ -145,7 +146,7 @@ will no longer be relying on unspecified behavior.
|
||||
* Signed | unsigned
|
||||
* Unaligned | aligned
|
||||
* 1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)
|
||||
* Choice of value type
|
||||
* Choice of value type
|
||||
|
||||
## Enums and typedefs
|
||||
|
||||
@ -210,7 +211,7 @@ and to improve code readability and searchability.
|
||||
|
||||
## Class template `endian_arithmetic`
|
||||
|
||||
An `endian_integer` is an integer byte-holder with user-specified endianness,
|
||||
`endian_arithmetic` is an integer byte-holder with user-specified endianness,
|
||||
value type, size, and alignment. The usual operations on arithmetic types are
|
||||
supplied.
|
||||
|
||||
@ -230,7 +231,6 @@ namespace boost
|
||||
template <order Order, class T, std::size_t n_bits,
|
||||
align Align = align::no>
|
||||
class endian_arithmetic
|
||||
: public endian_buffer<Order, T, n_bits, Align>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -243,8 +243,9 @@ namespace boost
|
||||
|
||||
endian_arithmetic& operator=(T v) noexcept;
|
||||
operator value_type() const noexcept;
|
||||
value_type value() const noexcept; // for exposition; see endian_buffer
|
||||
const char* data() const noexcept; // for exposition; see endian_buffer
|
||||
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
|
||||
@ -326,28 +327,28 @@ namespace boost
|
||||
typedef endian_arithmetic<order::little, double, 64> little_float64_t;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef implementation-defined_int8_t native_int8_t;
|
||||
typedef implementation-defined_int16_t native_int16_t;
|
||||
typedef implementation-defined_int24_t native_int24_t;
|
||||
typedef implementation-defined_int32_t native_int32_t;
|
||||
typedef implementation-defined_int40_t native_int40_t;
|
||||
typedef implementation-defined_int48_t native_int48_t;
|
||||
typedef implementation-defined_int56_t native_int56_t;
|
||||
typedef implementation-defined_int64_t native_int64_t;
|
||||
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 implementation-defined_uint8_t native_uint8_t;
|
||||
typedef implementation-defined_uint16_t native_uint16_t;
|
||||
typedef implementation-defined_uint24_t native_uint24_t;
|
||||
typedef implementation-defined_uint32_t native_uint32_t;
|
||||
typedef implementation-defined_uint40_t native_uint40_t;
|
||||
typedef implementation-defined_uint48_t native_uint48_t;
|
||||
typedef implementation-defined_uint56_t native_uint56_t;
|
||||
typedef implementation-defined_uint64_t native_uint64_t;
|
||||
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 implementation-defined_float32_t native_float32_t;
|
||||
typedef implementation-defined_float64_t native_float64_t;
|
||||
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;
|
||||
@ -388,9 +389,6 @@ namespace boost
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
The `implementation-defined` text above is either `big` or `little` according
|
||||
to the endianness of the platform.
|
||||
|
||||
The only supported value of `CHAR_BIT` is 8.
|
||||
|
||||
The valid values of `Nbits` are as follows:
|
||||
@ -434,6 +432,25 @@ endian_arithmetic& operator=(T v) noexcept;
|
||||
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;
|
||||
```
|
||||
@ -570,6 +587,7 @@ 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.
|
||||
|
||||
|
@ -231,12 +231,13 @@ namespace boost
|
||||
explicit endian_buffer(T v) noexcept;
|
||||
|
||||
endian_buffer& operator=(T v) noexcept;
|
||||
value_type value() const noexcept;
|
||||
const char* data() const 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
|
||||
unsigned char value_[Nbits / CHAR_BIT]; // exposition only
|
||||
};
|
||||
|
||||
// stream inserter
|
||||
@ -304,28 +305,28 @@ namespace boost
|
||||
typedef endian_buffer<order::little, double, 64> little_float64_buf_t;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef implementation-defined_int8_buf_t native_int8_buf_t;
|
||||
typedef implementation-defined_int16_buf_t native_int16_buf_t;
|
||||
typedef implementation-defined_int24_buf_t native_int24_buf_t;
|
||||
typedef implementation-defined_int32_buf_t native_int32_buf_t;
|
||||
typedef implementation-defined_int40_buf_t native_int40_buf_t;
|
||||
typedef implementation-defined_int48_buf_t native_int48_buf_t;
|
||||
typedef implementation-defined_int56_buf_t native_int56_buf_t;
|
||||
typedef implementation-defined_int64_buf_t native_int64_buf_t;
|
||||
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 implementation-defined_uint8_buf_t native_uint8_buf_t;
|
||||
typedef implementation-defined_uint16_buf_t native_uint16_buf_t;
|
||||
typedef implementation-defined_uint24_buf_t native_uint24_buf_t;
|
||||
typedef implementation-defined_uint32_buf_t native_uint32_buf_t;
|
||||
typedef implementation-defined_uint40_buf_t native_uint40_buf_t;
|
||||
typedef implementation-defined_uint48_buf_t native_uint48_buf_t;
|
||||
typedef implementation-defined_uint56_buf_t native_uint56_buf_t;
|
||||
typedef implementation-defined_uint64_buf_t native_uint64_buf_t;
|
||||
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 implementation-defined_float32_buf_t native_float32_buf_t;
|
||||
typedef implementation-defined_float64_buf_t native_float64_buf_t;
|
||||
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;
|
||||
@ -366,9 +367,6 @@ namespace boost
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
The `implementation-defined` text in typedefs above is either `big` or `little`
|
||||
according to the native endianness of the platform.
|
||||
|
||||
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>`.
|
||||
@ -425,7 +423,10 @@ value_type value() const noexcept;
|
||||
Returns:: `endian_load<T, Nbits/8, Order>( value_ )`.
|
||||
|
||||
```
|
||||
const char* data() const noexcept;
|
||||
unsigned char* data() noexcept;
|
||||
```
|
||||
```
|
||||
unsigned char const* data() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
|
@ -10,17 +10,32 @@ 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`
|
||||
* 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`
|
||||
|
@ -6,19 +6,15 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
////
|
||||
|
||||
[#choosing]
|
||||
# Choosing Approach
|
||||
# Choosing between Conversion Functions, Buffer Types, and Arithmetic Types
|
||||
:idprefix: choosing_
|
||||
|
||||
## Introduction
|
||||
|
||||
Deciding which is the best endianness approach (conversion functions, buffer
|
||||
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 diving into this page.
|
||||
|
||||
## Choosing between conversion functions, buffer types, and arithmetic types
|
||||
<<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
|
||||
@ -30,7 +26,7 @@ invest the time to study engineering trade-offs, use
|
||||
maintain. Use the _<<choosing_anticipating_need,anticipating need>>_ design
|
||||
pattern locally around performance hot spots like lengthy loops, if needed.
|
||||
|
||||
### Background
|
||||
## Background
|
||||
|
||||
A dealing with endianness usually implies a program portability or a data
|
||||
portability requirement, and often both. That means real programs dealing with
|
||||
@ -39,13 +35,13 @@ 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
|
||||
## 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
|
||||
### 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
|
||||
@ -121,7 +117,7 @@ write(data);
|
||||
|
||||
A later maintainer can add `third_party::func(data.v3)` and it will just-work.
|
||||
|
||||
#### Conversion explicitness
|
||||
### Conversion explicitness
|
||||
|
||||
*Endian conversion functions* and *buffer types* never perform implicit
|
||||
conversions. This gives users explicit control of when conversion occurs, and
|
||||
@ -131,7 +127,7 @@ may help avoid unnecessary conversions.
|
||||
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
|
||||
### 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
|
||||
@ -153,7 +149,7 @@ That's sufficient for many applications.
|
||||
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
|
||||
### Alignments
|
||||
|
||||
*Endianness conversion functions* only support aligned integer and
|
||||
floating-point types. That's sufficient for most applications.
|
||||
@ -180,7 +176,7 @@ struct S {
|
||||
};
|
||||
```
|
||||
|
||||
### Design patterns
|
||||
## 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.
|
||||
@ -189,7 +185,7 @@ 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)
|
||||
### Convert only as needed (i.e. lazy)
|
||||
|
||||
This pattern defers conversion to the point in the code where the data
|
||||
element is actually used.
|
||||
@ -198,7 +194,7 @@ 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
|
||||
### 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
|
||||
@ -213,7 +209,7 @@ 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
|
||||
### 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
|
||||
@ -264,9 +260,9 @@ 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
|
||||
## Use case examples
|
||||
|
||||
#### Porting endian unaware codebase
|
||||
### 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
|
||||
@ -279,7 +275,7 @@ 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
|
||||
### Porting endian aware codebase
|
||||
|
||||
An existing codebase runs on little-endian Linux systems. It already deals with
|
||||
endianness via
|
||||
@ -293,7 +289,7 @@ 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
|
||||
### 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
|
||||
@ -304,7 +300,7 @@ 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
|
||||
### 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
|
||||
|
@ -35,8 +35,20 @@ _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 3.9.1) except `bool` are collectively
|
||||
called the *endian types*.
|
||||
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
|
||||
|
||||
@ -81,6 +93,9 @@ namespace endian
|
||||
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>
|
||||
@ -216,37 +231,40 @@ reversed.
|
||||
|
||||
If `T` is a class type, the function:
|
||||
|
||||
* Returns 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, and;
|
||||
* Is a non-member function in the same namespace as `T` that can be found by
|
||||
argument dependent lookup (ADL).
|
||||
* 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 (in addition to `CopyConstructible`)
|
||||
##### EndianReversibleInplace requirements
|
||||
|
||||
[%header,cols=2*]
|
||||
|===
|
||||
|Expression |Requirements
|
||||
|`endian_reverse_inplace(mlx)`
|
||||
a|`T` is an endian type or a class type.
|
||||
a|`T` is an integral type, an enumeration type, `float`, `double`, a class type,
|
||||
or an array type.
|
||||
|
||||
If `T` is an endian type, reverses the order of bytes in `mlx`.
|
||||
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:
|
||||
|
||||
* Reverses the order of bytes of all data members of `mlx` that have types or
|
||||
arrays of types that meet the `EndianReversible` or `EndianReversibleInplace`
|
||||
requirements, and;
|
||||
* Is a non-member function in the same namespace as `T` that can be found by
|
||||
argument dependent lookup (ADL).
|
||||
* 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`, 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.
|
||||
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)
|
||||
|
||||
@ -273,7 +291,8 @@ Endian endian_reverse(Endian x) noexcept;
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires:: `Endian` must be a standard integral type that is not `bool`.
|
||||
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.
|
||||
|
||||
```
|
||||
@ -343,7 +362,20 @@ void endian_reverse_inplace(EndianReversible& x) noexcept;
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects:: `x = endian_reverse(x)`.
|
||||
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>
|
||||
@ -526,17 +558,15 @@ Effects::
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
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.
|
@ -1,79 +0,0 @@
|
||||
////
|
||||
Copyright 2011-2016 Beman Dawes
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
[#appendix_mini_review_topics]
|
||||
[appendix]
|
||||
# Endian Mini-Review
|
||||
|
||||
The results of the Boost.Endian formal review included a list of issues to be
|
||||
resolved before a mini-review.
|
||||
|
||||
The issues 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.
|
||||
|
||||
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.
|
@ -83,7 +83,8 @@ 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.
|
||||
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
|
||||
@ -113,10 +114,6 @@ 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.
|
||||
|
||||
## Choosing between conversion functions, buffer types, and arithmetic types
|
||||
|
||||
This section has been moved to its own <<choosing,Choosing the Approach>> page.
|
||||
|
||||
[#overview_intrinsics]
|
||||
## Built-in support for Intrinsics
|
||||
|
||||
@ -260,6 +257,28 @@ Iterations: 10'000'000'000, Intrinsics: `<cstdlib>` `_byteswap_ushort`, etc.
|
||||
|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
|
||||
|
||||
@ -326,11 +345,11 @@ 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 16, 32, and 64-bit
|
||||
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.
|
||||
|
||||
Why is there no floating point support?::
|
||||
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
|
||||
@ -338,116 +357,10 @@ 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. For all practical purposes, binary serialization and
|
||||
endianness for integers are one and the same problem. That is not true for
|
||||
floating point numbers, so binary serialization interfaces and formats for
|
||||
floating point does not fit well in an endian-based library.
|
||||
|
||||
## History
|
||||
|
||||
### Changes requested by formal review
|
||||
|
||||
The library was reworked from top to bottom to accommodate changes requested
|
||||
during the formal review. See <<appendix_mini_review_topics,Mini-Review>>
|
||||
page for details.
|
||||
|
||||
### 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.
|
||||
|
||||
[#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>>
|
||||
|===
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
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
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@ -37,7 +36,7 @@
|
||||
#include <iosfwd>
|
||||
#include <climits>
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
@ -146,47 +145,25 @@ namespace endian
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t;
|
||||
typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t;
|
||||
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
// native endian signed integer unaligned types
|
||||
typedef big_int8_t native_int8_t;
|
||||
typedef big_int16_t native_int16_t;
|
||||
typedef big_int24_t native_int24_t;
|
||||
typedef big_int32_t native_int32_t;
|
||||
typedef big_int40_t native_int40_t;
|
||||
typedef big_int48_t native_int48_t;
|
||||
typedef big_int56_t native_int56_t;
|
||||
typedef big_int64_t native_int64_t;
|
||||
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_t native_uint8_t;
|
||||
typedef big_uint16_t native_uint16_t;
|
||||
typedef big_uint24_t native_uint24_t;
|
||||
typedef big_uint32_t native_uint32_t;
|
||||
typedef big_uint40_t native_uint40_t;
|
||||
typedef big_uint48_t native_uint48_t;
|
||||
typedef big_uint56_t native_uint56_t;
|
||||
typedef big_uint64_t native_uint64_t;
|
||||
# else
|
||||
// native endian signed integer unaligned types
|
||||
typedef little_int8_t native_int8_t;
|
||||
typedef little_int16_t native_int16_t;
|
||||
typedef little_int24_t native_int24_t;
|
||||
typedef little_int32_t native_int32_t;
|
||||
typedef little_int40_t native_int40_t;
|
||||
typedef little_int48_t native_int48_t;
|
||||
typedef little_int56_t native_int56_t;
|
||||
typedef little_int64_t native_int64_t;
|
||||
|
||||
// native endian unsigned integer unaligned types
|
||||
typedef little_uint8_t native_uint8_t;
|
||||
typedef little_uint16_t native_uint16_t;
|
||||
typedef little_uint24_t native_uint24_t;
|
||||
typedef little_uint32_t native_uint32_t;
|
||||
typedef little_uint40_t native_uint40_t;
|
||||
typedef little_uint48_t native_uint48_t;
|
||||
typedef little_uint56_t native_uint56_t;
|
||||
typedef little_uint64_t native_uint64_t;
|
||||
# endif
|
||||
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 floating point types
|
||||
typedef endian_arithmetic<order::big, float, 32, align::no> big_float32_t;
|
||||
@ -200,12 +177,19 @@ namespace endian
|
||||
|
||||
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(align) Align>
|
||||
class endian_arithmetic:
|
||||
public endian_buffer<Order, T, n_bits, Align>
|
||||
class endian_arithmetic
|
||||
{
|
||||
private:
|
||||
|
||||
typedef endian_buffer<Order, T, n_bits, Align> inherited;
|
||||
typedef endian_buffer<Order, T, n_bits, Align> buffer_type;
|
||||
|
||||
#ifdef BOOST_ENDIAN_NO_CTORS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
|
||||
buffer_type buf_;
|
||||
|
||||
public:
|
||||
|
||||
@ -215,7 +199,7 @@ public:
|
||||
|
||||
endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic( T val ) BOOST_NOEXCEPT: inherited( val )
|
||||
BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic( T val ) BOOST_NOEXCEPT: buf_( val )
|
||||
{
|
||||
}
|
||||
|
||||
@ -223,15 +207,40 @@ public:
|
||||
|
||||
endian_arithmetic& operator=( T val ) BOOST_NOEXCEPT
|
||||
{
|
||||
inherited::operator=( val );
|
||||
buf_ = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type value() const BOOST_NOEXCEPT
|
||||
{
|
||||
return buf_.value();
|
||||
}
|
||||
|
||||
unsigned char const * data() const 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
|
||||
@ -350,7 +359,7 @@ public:
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <boost/endian/detail/endian_store.hpp>
|
||||
#include <boost/endian/detail/endian_load.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@ -39,7 +38,7 @@
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
@ -149,47 +148,25 @@ namespace endian
|
||||
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;
|
||||
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
// unaligned native endian signed integer buffers
|
||||
typedef big_int8_buf_t native_int8_buf_t;
|
||||
typedef big_int16_buf_t native_int16_buf_t;
|
||||
typedef big_int24_buf_t native_int24_buf_t;
|
||||
typedef big_int32_buf_t native_int32_buf_t;
|
||||
typedef big_int40_buf_t native_int40_buf_t;
|
||||
typedef big_int48_buf_t native_int48_buf_t;
|
||||
typedef big_int56_buf_t native_int56_buf_t;
|
||||
typedef big_int64_buf_t native_int64_buf_t;
|
||||
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_t native_uint8_buf_t;
|
||||
typedef big_uint16_buf_t native_uint16_buf_t;
|
||||
typedef big_uint24_buf_t native_uint24_buf_t;
|
||||
typedef big_uint32_buf_t native_uint32_buf_t;
|
||||
typedef big_uint40_buf_t native_uint40_buf_t;
|
||||
typedef big_uint48_buf_t native_uint48_buf_t;
|
||||
typedef big_uint56_buf_t native_uint56_buf_t;
|
||||
typedef big_uint64_buf_t native_uint64_buf_t;
|
||||
# else
|
||||
// unaligned native endian signed integer buffers
|
||||
typedef little_int8_buf_t native_int8_buf_t;
|
||||
typedef little_int16_buf_t native_int16_buf_t;
|
||||
typedef little_int24_buf_t native_int24_buf_t;
|
||||
typedef little_int32_buf_t native_int32_buf_t;
|
||||
typedef little_int40_buf_t native_int40_buf_t;
|
||||
typedef little_int48_buf_t native_int48_buf_t;
|
||||
typedef little_int56_buf_t native_int56_buf_t;
|
||||
typedef little_int64_buf_t native_int64_buf_t;
|
||||
|
||||
// unaligned native endian unsigned integer buffers
|
||||
typedef little_uint8_buf_t native_uint8_buf_t;
|
||||
typedef little_uint16_buf_t native_uint16_buf_t;
|
||||
typedef little_uint24_buf_t native_uint24_buf_t;
|
||||
typedef little_uint32_buf_t native_uint32_buf_t;
|
||||
typedef little_uint40_buf_t native_uint40_buf_t;
|
||||
typedef little_uint48_buf_t native_uint48_buf_t;
|
||||
typedef little_uint56_buf_t native_uint56_buf_t;
|
||||
typedef little_uint64_buf_t native_uint64_buf_t;
|
||||
# endif
|
||||
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 floating point buffers
|
||||
typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_t;
|
||||
@ -241,7 +218,9 @@ namespace endian
|
||||
template< BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits >
|
||||
class endian_buffer<Order, T, n_bits, align::no>
|
||||
{
|
||||
private:
|
||||
#ifdef BOOST_ENDIAN_NO_CTORS
|
||||
public:
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
|
||||
@ -273,9 +252,14 @@ public:
|
||||
return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );
|
||||
}
|
||||
|
||||
char const * data() const BOOST_NOEXCEPT
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast< char const* >( value_ );
|
||||
return value_;
|
||||
}
|
||||
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -323,9 +307,14 @@ public:
|
||||
return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );
|
||||
}
|
||||
|
||||
char const * data() const BOOST_NOEXCEPT
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast< char const* >( value_ );
|
||||
return value_;
|
||||
}
|
||||
|
||||
unsigned char * data() BOOST_NOEXCEPT
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -366,16 +355,21 @@ public:
|
||||
return value_;
|
||||
}
|
||||
|
||||
char const * data() const BOOST_NOEXCEPT
|
||||
unsigned char const * data() const BOOST_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast< char const* >( &value_ );
|
||||
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
|
||||
|
||||
|
@ -13,10 +13,8 @@
|
||||
#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_integral.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@ -47,7 +45,8 @@ namespace endian
|
||||
// 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;
|
||||
//
|
||||
// template<class T> inline BOOST_CONSTEXPR T endian_reverse( T x ) BOOST_NOEXCEPT;
|
||||
|
||||
// reverse byte order unless native endianness is big
|
||||
template <class EndianReversible >
|
||||
@ -110,9 +109,11 @@ namespace endian
|
||||
|
||||
// reverse in place
|
||||
// in detail/endian_reverse.hpp
|
||||
template <class EndianReversible>
|
||||
inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
|
||||
// Effects: x = endian_reverse(x)
|
||||
//
|
||||
// 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>
|
||||
@ -143,78 +144,28 @@ namespace endian
|
||||
|
||||
//----------------------------------- end synopsis -------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct is_endian_reversible: boost::integral_constant<bool,
|
||||
boost::is_class<T>::value || ( boost::is_integral<T>::value && !boost::is_same<T, bool>::value )>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible big_to_native( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible<EndianReversible>::value );
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
|
||||
return x;
|
||||
|
||||
#else
|
||||
|
||||
return endian_reverse(x);
|
||||
|
||||
#endif
|
||||
}
|
||||
return boost::endian::conditional_reverse<order::big, order::native>( x );
|
||||
}
|
||||
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_big( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible<EndianReversible>::value );
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
|
||||
return x;
|
||||
|
||||
#else
|
||||
|
||||
return endian_reverse(x);
|
||||
|
||||
#endif
|
||||
return boost::endian::conditional_reverse<order::native, order::big>( x );
|
||||
}
|
||||
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible little_to_native( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible<EndianReversible>::value );
|
||||
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
|
||||
return x;
|
||||
|
||||
#else
|
||||
|
||||
return endian_reverse(x);
|
||||
|
||||
#endif
|
||||
return boost::endian::conditional_reverse<order::little, order::native>( x );
|
||||
}
|
||||
|
||||
template <class EndianReversible>
|
||||
inline BOOST_CONSTEXPR EndianReversible native_to_little( EndianReversible x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible<EndianReversible>::value );
|
||||
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
|
||||
return x;
|
||||
|
||||
#else
|
||||
|
||||
return endian_reverse(x);
|
||||
|
||||
#endif
|
||||
return boost::endian::conditional_reverse<order::native, order::little>( x );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
@ -238,7 +189,7 @@ inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversib
|
||||
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( detail::is_endian_reversible<EndianReversible>::value );
|
||||
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>() );
|
||||
}
|
||||
|
||||
@ -247,7 +198,7 @@ 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( detail::is_endian_reversible<EndianReversible>::value );
|
||||
BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
|
||||
return from_order == to_order? x: endian_reverse( x );
|
||||
}
|
||||
|
||||
@ -255,92 +206,30 @@ inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x,
|
||||
// reverse-in-place implementation //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> struct is_endian_reversible_inplace: boost::integral_constant<bool,
|
||||
boost::is_class<T>::value || ( boost::is_integral<T>::value && !boost::is_same<T, bool>::value )>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void big_to_native_inplace( EndianReversibleInplace& ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void big_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
endian_reverse_inplace( x );
|
||||
boost::endian::conditional_reverse_inplace<order::big, order::native>( x );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_big_inplace( EndianReversibleInplace& ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_big_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
endian_reverse_inplace( x );
|
||||
boost::endian::conditional_reverse_inplace<order::native, order::big>( x );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void little_to_native_inplace( EndianReversibleInplace& ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void little_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
endian_reverse_inplace( x );
|
||||
boost::endian::conditional_reverse_inplace<order::little, order::native>( x );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_little_inplace( EndianReversibleInplace& ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class EndianReversibleInplace>
|
||||
inline void native_to_little_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
endian_reverse_inplace( x );
|
||||
boost::endian::conditional_reverse_inplace<order::native, order::little>( x );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@ -361,7 +250,11 @@ inline void conditional_reverse_inplace_impl( EndianReversibleInplace& x, boost:
|
||||
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( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
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>() );
|
||||
}
|
||||
|
||||
@ -370,7 +263,10 @@ 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( detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
|
||||
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 )
|
||||
{
|
||||
|
@ -1,15 +1,18 @@
|
||||
#ifndef BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
|
||||
#define BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Copyright 2019, 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
// 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>
|
||||
@ -62,7 +65,7 @@ inline uint16_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint16_t x ) BOOST_N
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint32_t x) BOOST_NOEXCEPT
|
||||
inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
|
||||
@ -76,7 +79,7 @@ inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint32_t x) BOOST_NOE
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint64_t x) BOOST_NOEXCEPT
|
||||
inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_ENDIAN_NO_INTRINSICS
|
||||
|
||||
@ -91,26 +94,84 @@ inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint64_t x) BOOST_NOE
|
||||
# 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
|
||||
// T is non-bool integral or scoped enumeration type
|
||||
|
||||
template<class T> inline BOOST_CONSTEXPR T endian_reverse( T x ) BOOST_NOEXCEPT
|
||||
template<class T> inline BOOST_CONSTEXPR
|
||||
typename enable_if_< !is_class<T>::value, T >::type
|
||||
endian_reverse( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value && !is_same<T, bool>::value );
|
||||
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 ) ) );
|
||||
}
|
||||
|
||||
template <class EndianReversible>
|
||||
inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT
|
||||
// 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
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
@ -40,6 +41,15 @@ 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
|
||||
|
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
|
@ -9,6 +9,7 @@
|
||||
#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>
|
||||
@ -28,7 +29,7 @@ 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_copy<T>::value && boost::has_trivial_assign<T>::value && boost::has_trivial_destructor<T>::value> {};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -7,7 +7,36 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
|
||||
#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
|
||||
{
|
||||
@ -16,20 +45,15 @@ namespace endian
|
||||
|
||||
BOOST_SCOPED_ENUM_START(order)
|
||||
{
|
||||
big, little,
|
||||
big,
|
||||
little,
|
||||
native = BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER
|
||||
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
|
||||
native = big
|
||||
|
||||
# else
|
||||
|
||||
native = little
|
||||
|
||||
# endif
|
||||
}; BOOST_SCOPED_ENUM_END
|
||||
|
||||
} // namespace endian
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_ENDIAN_NATIVE_ORDER_INITIALIZER
|
||||
|
||||
#endif // BOOST_ENDIAN_DETAIL_ORDER_HPP_INCLUDED
|
||||
|
@ -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()
|
@ -13,61 +13,60 @@ import testing ;
|
||||
project
|
||||
: default-build
|
||||
|
||||
<warnings>all
|
||||
<warnings>pedantic
|
||||
|
||||
: requirements
|
||||
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
|
||||
<toolset>gcc:<cxxflags>-Wno-long-long
|
||||
<toolset>gcc-4.4.7:<cxxflags>-Wno-strict-aliasing
|
||||
<toolset>gcc-4.4.7:<cxxflags>-Wno-sign-compare
|
||||
<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 buffer_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : buffer_test_ni ;
|
||||
run-ni buffer_test.cpp ;
|
||||
|
||||
run endian_test.cpp ;
|
||||
run endian_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_test_ni ;
|
||||
run-ni endian_test.cpp ;
|
||||
|
||||
run endian_operations_test.cpp ;
|
||||
run endian_operations_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_operations_test_ni ;
|
||||
run-ni endian_operations_test.cpp ;
|
||||
|
||||
run endian_in_union_test.cpp ;
|
||||
|
||||
run conversion_test.cpp ;
|
||||
run conversion_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : conversion_test_ni ;
|
||||
run-ni conversion_test.cpp ;
|
||||
|
||||
run intrinsic_test.cpp ;
|
||||
|
||||
run quick.cpp ;
|
||||
|
||||
local allow-warnings =
|
||||
"-<toolset>msvc:<warnings-as-errors>on"
|
||||
"-<toolset>gcc:<warnings-as-errors>on"
|
||||
"-<toolset>clang:<warnings-as-errors>on" ;
|
||||
|
||||
compile spirit_conflict_test.cpp
|
||||
: $(allow-warnings) ;
|
||||
|
||||
run endian_reverse_test.cpp ;
|
||||
run endian_reverse_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_reverse_test_ni ;
|
||||
run-ni endian_reverse_test.cpp ;
|
||||
|
||||
run endian_load_test.cpp ;
|
||||
run endian_load_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_load_test_ni ;
|
||||
run-ni endian_load_test.cpp ;
|
||||
|
||||
run endian_store_test.cpp ;
|
||||
run endian_store_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_store_test_ni ;
|
||||
run-ni endian_store_test.cpp ;
|
||||
|
||||
run endian_ld_st_roundtrip_test.cpp ;
|
||||
run endian_ld_st_roundtrip_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_ld_st_roundtrip_test_ni ;
|
||||
run-ni endian_ld_st_roundtrip_test.cpp ;
|
||||
|
||||
run endian_arithmetic_test.cpp ;
|
||||
run endian_arithmetic_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : endian_arithmetic_test_ni ;
|
||||
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 ;
|
||||
|
||||
@ -75,10 +74,38 @@ 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 load_convenience_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : load_convenience_test_ni ;
|
||||
run-ni load_convenience_test.cpp ;
|
||||
|
||||
run store_convenience_test.cpp ;
|
||||
run store_convenience_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : store_convenience_test_ni ;
|
||||
run-ni store_convenience_test.cpp ;
|
||||
|
||||
run float_typedef_test.cpp ;
|
||||
run float_typedef_test.cpp : : : <define>BOOST_ENDIAN_NO_INTRINSICS : float_typedef_test_ni ;
|
||||
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();
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
#include <boost/endian/detail/disable_warnings.hpp>
|
||||
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <iostream>
|
||||
@ -322,4 +321,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>
|
||||
|
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>)
|
@ -2,7 +2,7 @@
|
||||
# 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)
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(cmake_subdir_test LANGUAGES CXX)
|
||||
|
||||
@ -20,13 +20,13 @@ endfunction()
|
||||
|
||||
boost_add_subdir(config)
|
||||
boost_add_subdir(core)
|
||||
boost_add_subdir(predef)
|
||||
boost_add_subdir(static_assert)
|
||||
boost_add_subdir(type_traits)
|
||||
|
||||
# secondary dependencies
|
||||
|
||||
boost_add_subdir(assert)
|
||||
boost_add_subdir(throw_exception)
|
||||
|
||||
# --target check
|
||||
|
||||
|
@ -7,14 +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/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;
|
||||
@ -38,63 +48,43 @@ template <class T> inline T std_endian_reverse(T x) BOOST_NOEXCEPT
|
||||
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);}
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
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);}
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
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);}
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
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);}
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
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;
|
||||
|
||||
x = 0;
|
||||
|
||||
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()
|
||||
@ -108,13 +98,16 @@ namespace
|
||||
|
||||
// validate the values used by the tests below
|
||||
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
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);
|
||||
# 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
|
||||
|
||||
@ -338,6 +331,19 @@ 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;
|
||||
@ -376,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();
|
||||
}
|
@ -13,7 +13,6 @@
|
||||
|
||||
#define BOOST_ENDIAN_DEPRECATED_NAMES
|
||||
#include <boost/endian/endian.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <iostream>
|
||||
@ -181,4 +180,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>
|
||||
|
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();
|
||||
}
|
@ -29,7 +29,6 @@
|
||||
#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>
|
||||
@ -489,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();
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,24 @@ 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;
|
||||
@ -114,6 +132,48 @@ template<class T> void test()
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
@ -152,5 +212,12 @@ int main()
|
||||
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();
|
||||
}
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
@ -28,6 +27,10 @@
|
||||
#include <cstdlib> // for atoi(), exit()
|
||||
#include <cstring> // for memcmp()
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
using namespace std; // Not the best programming practice, but I
|
||||
using namespace boost; // want to verify this combination of using
|
||||
using namespace boost::endian; // namespaces works. See endian_operations_test
|
||||
@ -102,11 +105,7 @@ namespace
|
||||
template <class Endian>
|
||||
inline void verify_native_representation( int line )
|
||||
{
|
||||
# if BOOST_ENDIAN_BIG_BYTE
|
||||
verify_representation<Endian>( true, line );
|
||||
# else
|
||||
verify_representation<Endian>( false, line );
|
||||
# endif
|
||||
verify_representation<Endian>( order::native == order::big, line );
|
||||
}
|
||||
|
||||
// detect_order -----------------------------------------------------//
|
||||
@ -124,22 +123,24 @@ namespace
|
||||
if ( memcmp( v.c, "\x8\7\6\5\4\3\2\1", 8) == 0 )
|
||||
{
|
||||
cout << "This machine is little-endian.\n";
|
||||
# if !BOOST_ENDIAN_LITTLE_BYTE
|
||||
cout << "yet boost/predef/other/endian.h does not define BOOST_ENDIAN_LITTLE_BYTE.\n"
|
||||
if( order::native != order::little )
|
||||
{
|
||||
cout << "yet boost::endian::order::native does not equal boost::endian::order::little.\n"
|
||||
"The Boost Endian library must be revised to work correctly on this system.\n"
|
||||
"Please report this problem to the Boost mailing list.\n";
|
||||
exit(1);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
else if ( memcmp( v.c, "\1\2\3\4\5\6\7\x8", 8) == 0 )
|
||||
{
|
||||
cout << "This machine is big-endian.\n";
|
||||
# if !BOOST_ENDIAN_BIG_BYTE
|
||||
cout << "yet boost/predef/other/endian.h does not define BOOST_ENDIAN_BIG_BYTE.\n"
|
||||
if( order::native != order::big )
|
||||
{
|
||||
cout << "yet boost::endian::order::native does not equal boost::endian::order::big.\n"
|
||||
"The Boost Endian library must be revised to work correctly on this system.\n"
|
||||
"Please report this problem to the Boost mailing list.\n";
|
||||
exit(1);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -225,75 +226,75 @@ namespace
|
||||
little_uint32_at little_align_uint32;
|
||||
little_uint64_at little_align_uint64;
|
||||
|
||||
VERIFY(big_8.data() == reinterpret_cast<const char *>(&big_8));
|
||||
VERIFY(big_16.data() == reinterpret_cast<const char *>(&big_16));
|
||||
VERIFY(big_24.data() == reinterpret_cast<const char *>(&big_24));
|
||||
VERIFY(big_32.data() == reinterpret_cast<const char *>(&big_32));
|
||||
VERIFY(big_40.data() == reinterpret_cast<const char *>(&big_40));
|
||||
VERIFY(big_48.data() == reinterpret_cast<const char *>(&big_48));
|
||||
VERIFY(big_56.data() == reinterpret_cast<const char *>(&big_56));
|
||||
VERIFY(big_64.data() == reinterpret_cast<const char *>(&big_64));
|
||||
VERIFY(big_8.data() == reinterpret_cast<const unsigned char *>(&big_8));
|
||||
VERIFY(big_16.data() == reinterpret_cast<const unsigned char *>(&big_16));
|
||||
VERIFY(big_24.data() == reinterpret_cast<const unsigned char *>(&big_24));
|
||||
VERIFY(big_32.data() == reinterpret_cast<const unsigned char *>(&big_32));
|
||||
VERIFY(big_40.data() == reinterpret_cast<const unsigned char *>(&big_40));
|
||||
VERIFY(big_48.data() == reinterpret_cast<const unsigned char *>(&big_48));
|
||||
VERIFY(big_56.data() == reinterpret_cast<const unsigned char *>(&big_56));
|
||||
VERIFY(big_64.data() == reinterpret_cast<const unsigned char *>(&big_64));
|
||||
|
||||
VERIFY(big_u8.data() == reinterpret_cast<const char *>(&big_u8));
|
||||
VERIFY(big_u16.data() == reinterpret_cast<const char *>(&big_u16));
|
||||
VERIFY(big_u24.data() == reinterpret_cast<const char *>(&big_u24));
|
||||
VERIFY(big_u32.data() == reinterpret_cast<const char *>(&big_u32));
|
||||
VERIFY(big_u40.data() == reinterpret_cast<const char *>(&big_u40));
|
||||
VERIFY(big_u48.data() == reinterpret_cast<const char *>(&big_u48));
|
||||
VERIFY(big_u56.data() == reinterpret_cast<const char *>(&big_u56));
|
||||
VERIFY(big_u64.data() == reinterpret_cast<const char *>(&big_u64));
|
||||
VERIFY(big_u8.data() == reinterpret_cast<const unsigned char *>(&big_u8));
|
||||
VERIFY(big_u16.data() == reinterpret_cast<const unsigned char *>(&big_u16));
|
||||
VERIFY(big_u24.data() == reinterpret_cast<const unsigned char *>(&big_u24));
|
||||
VERIFY(big_u32.data() == reinterpret_cast<const unsigned char *>(&big_u32));
|
||||
VERIFY(big_u40.data() == reinterpret_cast<const unsigned char *>(&big_u40));
|
||||
VERIFY(big_u48.data() == reinterpret_cast<const unsigned char *>(&big_u48));
|
||||
VERIFY(big_u56.data() == reinterpret_cast<const unsigned char *>(&big_u56));
|
||||
VERIFY(big_u64.data() == reinterpret_cast<const unsigned char *>(&big_u64));
|
||||
|
||||
VERIFY(little_8.data() == reinterpret_cast<const char *>(&little_8));
|
||||
VERIFY(little_16.data() == reinterpret_cast<const char *>(&little_16));
|
||||
VERIFY(little_24.data() == reinterpret_cast<const char *>(&little_24));
|
||||
VERIFY(little_32.data() == reinterpret_cast<const char *>(&little_32));
|
||||
VERIFY(little_40.data() == reinterpret_cast<const char *>(&little_40));
|
||||
VERIFY(little_48.data() == reinterpret_cast<const char *>(&little_48));
|
||||
VERIFY(little_56.data() == reinterpret_cast<const char *>(&little_56));
|
||||
VERIFY(little_64.data() == reinterpret_cast<const char *>(&little_64));
|
||||
VERIFY(little_8.data() == reinterpret_cast<const unsigned char *>(&little_8));
|
||||
VERIFY(little_16.data() == reinterpret_cast<const unsigned char *>(&little_16));
|
||||
VERIFY(little_24.data() == reinterpret_cast<const unsigned char *>(&little_24));
|
||||
VERIFY(little_32.data() == reinterpret_cast<const unsigned char *>(&little_32));
|
||||
VERIFY(little_40.data() == reinterpret_cast<const unsigned char *>(&little_40));
|
||||
VERIFY(little_48.data() == reinterpret_cast<const unsigned char *>(&little_48));
|
||||
VERIFY(little_56.data() == reinterpret_cast<const unsigned char *>(&little_56));
|
||||
VERIFY(little_64.data() == reinterpret_cast<const unsigned char *>(&little_64));
|
||||
|
||||
VERIFY(little_u8.data() == reinterpret_cast<const char *>(&little_u8));
|
||||
VERIFY(little_u16.data() == reinterpret_cast<const char *>(&little_u16));
|
||||
VERIFY(little_u24.data() == reinterpret_cast<const char *>(&little_u24));
|
||||
VERIFY(little_u32.data() == reinterpret_cast<const char *>(&little_u32));
|
||||
VERIFY(little_u40.data() == reinterpret_cast<const char *>(&little_u40));
|
||||
VERIFY(little_u48.data() == reinterpret_cast<const char *>(&little_u48));
|
||||
VERIFY(little_u56.data() == reinterpret_cast<const char *>(&little_u56));
|
||||
VERIFY(little_u64.data() == reinterpret_cast<const char *>(&little_u64));
|
||||
VERIFY(little_u8.data() == reinterpret_cast<const unsigned char *>(&little_u8));
|
||||
VERIFY(little_u16.data() == reinterpret_cast<const unsigned char *>(&little_u16));
|
||||
VERIFY(little_u24.data() == reinterpret_cast<const unsigned char *>(&little_u24));
|
||||
VERIFY(little_u32.data() == reinterpret_cast<const unsigned char *>(&little_u32));
|
||||
VERIFY(little_u40.data() == reinterpret_cast<const unsigned char *>(&little_u40));
|
||||
VERIFY(little_u48.data() == reinterpret_cast<const unsigned char *>(&little_u48));
|
||||
VERIFY(little_u56.data() == reinterpret_cast<const unsigned char *>(&little_u56));
|
||||
VERIFY(little_u64.data() == reinterpret_cast<const unsigned char *>(&little_u64));
|
||||
|
||||
VERIFY(native_8.data() == reinterpret_cast<const char *>(&native_8));
|
||||
VERIFY(native_16.data() == reinterpret_cast<const char *>(&native_16));
|
||||
VERIFY(native_24.data() == reinterpret_cast<const char *>(&native_24));
|
||||
VERIFY(native_32.data() == reinterpret_cast<const char *>(&native_32));
|
||||
VERIFY(native_40.data() == reinterpret_cast<const char *>(&native_40));
|
||||
VERIFY(native_48.data() == reinterpret_cast<const char *>(&native_48));
|
||||
VERIFY(native_56.data() == reinterpret_cast<const char *>(&native_56));
|
||||
VERIFY(native_64.data() == reinterpret_cast<const char *>(&native_64));
|
||||
VERIFY(native_8.data() == reinterpret_cast<const unsigned char *>(&native_8));
|
||||
VERIFY(native_16.data() == reinterpret_cast<const unsigned char *>(&native_16));
|
||||
VERIFY(native_24.data() == reinterpret_cast<const unsigned char *>(&native_24));
|
||||
VERIFY(native_32.data() == reinterpret_cast<const unsigned char *>(&native_32));
|
||||
VERIFY(native_40.data() == reinterpret_cast<const unsigned char *>(&native_40));
|
||||
VERIFY(native_48.data() == reinterpret_cast<const unsigned char *>(&native_48));
|
||||
VERIFY(native_56.data() == reinterpret_cast<const unsigned char *>(&native_56));
|
||||
VERIFY(native_64.data() == reinterpret_cast<const unsigned char *>(&native_64));
|
||||
|
||||
VERIFY(native_u8.data() == reinterpret_cast<const char *>(&native_u8));
|
||||
VERIFY(native_u16.data() == reinterpret_cast<const char *>(&native_u16));
|
||||
VERIFY(native_u24.data() == reinterpret_cast<const char *>(&native_u24));
|
||||
VERIFY(native_u32.data() == reinterpret_cast<const char *>(&native_u32));
|
||||
VERIFY(native_u40.data() == reinterpret_cast<const char *>(&native_u40));
|
||||
VERIFY(native_u48.data() == reinterpret_cast<const char *>(&native_u48));
|
||||
VERIFY(native_u56.data() == reinterpret_cast<const char *>(&native_u56));
|
||||
VERIFY(native_u64.data() == reinterpret_cast<const char *>(&native_u64));
|
||||
VERIFY(native_u8.data() == reinterpret_cast<const unsigned char *>(&native_u8));
|
||||
VERIFY(native_u16.data() == reinterpret_cast<const unsigned char *>(&native_u16));
|
||||
VERIFY(native_u24.data() == reinterpret_cast<const unsigned char *>(&native_u24));
|
||||
VERIFY(native_u32.data() == reinterpret_cast<const unsigned char *>(&native_u32));
|
||||
VERIFY(native_u40.data() == reinterpret_cast<const unsigned char *>(&native_u40));
|
||||
VERIFY(native_u48.data() == reinterpret_cast<const unsigned char *>(&native_u48));
|
||||
VERIFY(native_u56.data() == reinterpret_cast<const unsigned char *>(&native_u56));
|
||||
VERIFY(native_u64.data() == reinterpret_cast<const unsigned char *>(&native_u64));
|
||||
|
||||
VERIFY(big_align_int16.data() == reinterpret_cast<const char *>(&big_align_int16));
|
||||
VERIFY(big_align_int32.data() == reinterpret_cast<const char *>(&big_align_int32));
|
||||
VERIFY(big_align_int64.data() == reinterpret_cast<const char *>(&big_align_int64));
|
||||
VERIFY(big_align_int16.data() == reinterpret_cast<const unsigned char *>(&big_align_int16));
|
||||
VERIFY(big_align_int32.data() == reinterpret_cast<const unsigned char *>(&big_align_int32));
|
||||
VERIFY(big_align_int64.data() == reinterpret_cast<const unsigned char *>(&big_align_int64));
|
||||
|
||||
VERIFY(big_align_uint16.data() == reinterpret_cast<const char *>(&big_align_uint16));
|
||||
VERIFY(big_align_uint32.data() == reinterpret_cast<const char *>(&big_align_uint32));
|
||||
VERIFY(big_align_uint64.data() == reinterpret_cast<const char *>(&big_align_uint64));
|
||||
VERIFY(big_align_uint16.data() == reinterpret_cast<const unsigned char *>(&big_align_uint16));
|
||||
VERIFY(big_align_uint32.data() == reinterpret_cast<const unsigned char *>(&big_align_uint32));
|
||||
VERIFY(big_align_uint64.data() == reinterpret_cast<const unsigned char *>(&big_align_uint64));
|
||||
|
||||
VERIFY(little_align_int16.data() == reinterpret_cast<const char *>(&little_align_int16));
|
||||
VERIFY(little_align_int32.data() == reinterpret_cast<const char *>(&little_align_int32));
|
||||
VERIFY(little_align_int64.data() == reinterpret_cast<const char *>(&little_align_int64));
|
||||
VERIFY(little_align_int16.data() == reinterpret_cast<const unsigned char *>(&little_align_int16));
|
||||
VERIFY(little_align_int32.data() == reinterpret_cast<const unsigned char *>(&little_align_int32));
|
||||
VERIFY(little_align_int64.data() == reinterpret_cast<const unsigned char *>(&little_align_int64));
|
||||
|
||||
VERIFY(little_align_uint16.data() == reinterpret_cast<const char *>(&little_align_uint16));
|
||||
VERIFY(little_align_uint32.data() == reinterpret_cast<const char *>(&little_align_uint32));
|
||||
VERIFY(little_align_uint64.data() == reinterpret_cast<const char *>(&little_align_uint64));
|
||||
VERIFY(little_align_uint16.data() == reinterpret_cast<const unsigned char *>(&little_align_uint16));
|
||||
VERIFY(little_align_uint32.data() == reinterpret_cast<const unsigned char *>(&little_align_uint32));
|
||||
VERIFY(little_align_uint64.data() == reinterpret_cast<const unsigned char *>(&little_align_uint64));
|
||||
|
||||
}
|
||||
|
||||
@ -836,3 +837,16 @@ int cpp_main( int argc, char * argv[] )
|
||||
|
||||
return err_count ? 1 : 0;
|
||||
} // main
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main( argc, argv );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
std::cout << "Exception: " << x.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,17 @@ template<class T> struct align
|
||||
}
|
||||
};
|
||||
|
||||
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? 2 * sizeof(U): 1 + sizeof(U) );
|
||||
BOOST_TEST_EQ( sizeof(x), aligned? sizeof( align2<U> ): 1 + sizeof(U) );
|
||||
|
||||
BOOST_TEST_EQ( x.v.value(), y );
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ int main()
|
||||
uint32 y4 = BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x4);
|
||||
BOOST_TEST_EQ( y4, 0x44332211UL );
|
||||
|
||||
uint64 x8 = 0x1122334455667788U;
|
||||
uint64 x8 = 0x1122334455667788ULL;
|
||||
uint64 y8 = BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x8);
|
||||
BOOST_TEST_EQ( y8, 0x8877665544332211ULL );
|
||||
|
||||
|
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();
|
||||
}
|
87
test/order_test.cpp
Normal file
87
test/order_test.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// 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/order.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::uint64_t v = static_cast<boost::uint64_t>( 0x0102030405060708ull );
|
||||
byte_span v2( reinterpret_cast<unsigned char const*>( &v ), sizeof(v) );
|
||||
|
||||
if( boost::endian::order::native == boost::endian::order::little )
|
||||
{
|
||||
unsigned char w[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
BOOST_TEST_EQ( v2, byte_span( w ) );
|
||||
}
|
||||
else if( boost::endian::order::native == boost::endian::order::big )
|
||||
{
|
||||
unsigned char w[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
BOOST_TEST_EQ( v2, byte_span( w ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ERROR( "boost::endian::order::native is neither big nor little" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
38
test/packed_arithmetic_test.cpp
Normal file
38
test/packed_arithmetic_test.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE( "Skipping test because __GNUC__ is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_ENDIAN_FORCE_PODNESS
|
||||
#define BOOST_ENDIAN_NO_CTORS
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
struct X
|
||||
{
|
||||
big_uint16_t a;
|
||||
native_float64_t b;
|
||||
little_uint16_t c;
|
||||
} __attribute__((packed));
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( sizeof(big_uint16_t), 2 );
|
||||
BOOST_TEST_EQ( sizeof(native_float64_t), 8 );
|
||||
BOOST_TEST_EQ( sizeof(little_uint16_t), 2 );
|
||||
|
||||
BOOST_TEST_EQ( sizeof(X), 12 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
38
test/packed_buffer_test.cpp
Normal file
38
test/packed_buffer_test.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE( "Skipping test because __GNUC__ is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_ENDIAN_FORCE_PODNESS
|
||||
#define BOOST_ENDIAN_NO_CTORS
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::endian;
|
||||
|
||||
struct X
|
||||
{
|
||||
big_uint16_buf_t a;
|
||||
native_float64_buf_t b;
|
||||
little_uint16_buf_t c;
|
||||
} __attribute__((packed));
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( sizeof(big_uint16_buf_t), 2 );
|
||||
BOOST_TEST_EQ( sizeof(native_float64_buf_t), 8 );
|
||||
BOOST_TEST_EQ( sizeof(little_uint16_buf_t), 2 );
|
||||
|
||||
BOOST_TEST_EQ( sizeof(X), 12 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
// 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: 4510 ) // default constructor not generated
|
||||
# pragma warning( disable: 4512 ) // assignment operator not generated
|
||||
# pragma warning( disable: 4610 ) // class can never be instantiated
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
|
||||
struct record
|
||||
{
|
||||
boost::endian::big_int16_t type;
|
||||
|
||||
record( boost::int16_t t )
|
||||
{
|
||||
type = t;
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user