Compare commits

...

90 Commits

Author SHA1 Message Date
7719090004 glob headers 2022-07-05 10:48:11 +02:00
d1a95acee2 Rework as esp-idf component 2022-07-04 20:14:59 +02:00
0dab6737eb Use <warnings>pedantic 2022-06-28 16:40:40 +03:00
a3f658b15d Use <warnings>extra 2022-06-28 14:15:40 +03:00
423b695ec0 Remove spirit_conflict_test.cpp; Spirit has been fixed 2022-06-28 02:41:50 +03:00
5ec08e62cd Update test/Jamfile 2022-06-28 02:10:34 +03:00
e35a48c0ea Update ci.yml 2022-06-27 21:46:32 +03:00
a9ab336f89 Reenable ASAN for GCC 12 -m32 2022-06-27 20:31:39 +03:00
fa3dd0b853 Remove g++ 4.4 -m32 due to 'constant too large for long' warnings 2022-06-27 20:29:20 +03:00
39f9394e38 Update intrinsic_test.cpp 2022-06-27 20:09:19 +03:00
3951447dac Update test/Jamfile 2022-06-27 19:48:06 +03:00
3a53394b31 Update .drone.jsonnet 2022-06-27 19:45:49 +03:00
c54c199640 Add Drone support 2022-06-27 16:00:17 +03:00
141af01ead Add throw_exception to cmake_subdir_test 2021-11-03 18:21:29 +02:00
647e1363a8 Add CMake tests to ci.yml 2021-11-03 16:26:00 +02:00
af016adda1 Fix duplicate test under CMake 2021-11-03 16:19:31 +02:00
ccc1def8c9 Use -ffloat-store for endian_arithmetic_test to avoid -m32 failures 2021-10-29 05:49:25 +03:00
e1d8b67380 Enable syntax highlighting 2021-10-28 23:11:07 +03:00
6dc25d067d type_name<T> does not support incomplete types 2021-10-26 00:50:59 +03:00
ab54773e26 Update ci.yml 2021-10-26 00:48:13 +03:00
14dd639312 Update .github/workflows 2021-04-19 18:13:45 +03:00
108c01316f Add -DBUILD_TESTING=ON to .yml files; it's not default anymore 2021-03-19 03:55:59 +02:00
daca1dce12 Update .travis.yml 2021-03-19 00:06:34 +02:00
ef89beccfd Fix .travis.yml 2021-03-18 16:24:36 +02:00
3e34e8c011 Update .travis.yml 2021-03-18 04:28:27 +02:00
40fdf66f24 Remove xcode6.4 from Travis 2021-01-20 21:29:15 +02:00
783c7e6242 Add .github/workflows 2021-01-20 00:35:21 +02:00
6477f4abe6 Merge pull request #47 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-20 00:28:30 +02:00
fa2d87176e [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-19 16:27:33 -05:00
eed8b47703 Update maintainer e-mail 2020-12-12 00:55:52 +02:00
9420226cbc Update maintainer in meta/libraries.json 2020-12-01 19:22:24 -05:00
f5b7193778 Update revision history 2020-10-15 15:51:01 +03:00
b0b9622ceb Use an unaligned type instead of double in packed_*_test 2020-10-07 01:37:03 +03:00
84f15c4fb2 Add more sizeof tests to packed_buffer_test 2020-10-06 22:00:35 +03:00
295c225e9e Use address-model=32 for msvc-9.0, 10.0, 11.0 2020-10-06 21:59:06 +03:00
3853f80886 Update documentation 2020-10-06 19:42:08 +03:00
7832a88828 Make endian_arithmetic's data member public when BOOST_ENDIAN_NO_CTORS is defined; add test 2020-10-06 19:34:40 +03:00
9f122a913c Remove inheritance of endian_arithmetic from endian_buffer 2020-10-06 19:16:13 +03:00
94b5b7c73f Add test for arithmetic -> buffer conversions 2020-10-06 19:08:25 +03:00
914d7d5c8d Make endian_buffer::value_ public when BOOST_ENDIAN_NO_CTORS is defined; add test 2020-10-06 18:53:56 +03:00
dffcf99ca6 Use pip install --user 2020-06-04 16:18:03 +03:00
4a7242be23 Remove boost_install call from CMakeLists.txt 2020-06-04 15:59:28 +03:00
f07be92a32 Add noexcept to the array overload of endian_reverse_inplace 2020-05-22 17:41:26 +03:00
c489997d37 Document endian_reverse_inplace for arrays 2020-05-22 17:34:24 +03:00
496e99cbad Update changelog 2020-05-22 17:20:23 +03:00
e2b622d3da Fix typo 2020-05-22 17:16:43 +03:00
9ee301b103 Enable conditional_reverse_inplace for arrays 2020-05-05 21:24:02 +03:00
d46d2916a8 Add more tests to endian_reverse_test3/4 2020-05-05 20:18:58 +03:00
62091e5d0c Add an overload of endian_reverse_inplace for arrays 2020-05-05 20:06:21 +03:00
a6e1da6a79 Remove extra spaces 2020-05-03 18:29:48 +03:00
e2fe1d7743 Merge pull request #43 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74. Change __BORLANDC__ to BOOST_BORLANDC and __CODEGEARC__ to BOOST_CODE…
2020-05-03 17:16:05 +03:00
5df5bc062f Update README 2020-05-03 17:11:50 +03:00
9d248e0f5e Update documentation 2020-05-03 04:46:35 +03:00
3e2890c243 Enable endian_reverse_inplace for integral/enum/float/double 2020-05-03 03:22:21 +03:00
8e617a69d1 Enable scoped enums in endian_reverse 2020-05-03 00:10:26 +03:00
74b73c5c03 Move is_endian_reversible, is_endian_reversible_inplace to detail/endian_reverse.hpp 2020-05-02 22:15:08 +03:00
7f025ef4b6 Change >> to > > for C++03 2020-05-02 20:32:42 +03:00
ceb58197d5 Add detail/is_scoped_enum.hpp 2020-05-02 20:23:35 +03:00
21eed3fd59 Update is_trivially_copyable to also check has_trivial_destructor in the fallback case 2020-05-02 02:25:15 +03:00
0f33f25eeb Change __BORLANDC__ to BOOST_BORLANDC and __CODEGEARC__ to BOOST_CODEGEARC, which are defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-30 20:55:52 -04:00
e1b7981a53 ppc64le doesn't have 32 bit 2020-03-13 00:45:03 +02:00
2b101c64a9 Fix alignment test for 32 bit Linux/macOS 2020-03-12 00:59:43 +02:00
38598d02a3 Only use address-model=32,64 on selected Travis configurations 2020-03-12 00:50:31 +02:00
073ba8ad7d Add address-model=32,64 to Travis 2020-03-11 15:18:12 +02:00
a5ae1bb09f Remove stray sentences 2020-01-22 03:48:38 +02:00
520d37eb9f Update synopsis of native buffer and arithmetic typedefs 2020-01-22 01:26:11 +02:00
81ac17540a Update overview; move 'choosing approach' section after it 2020-01-21 04:26:38 +02:00
7eaa25ec2a Delete the no-longer referenced mini_review_topics.adoc 2020-01-21 03:59:00 +02:00
297a146950 Move history and acknowledgments to an appendix 2020-01-21 03:58:05 +02:00
627fa385f1 Clarify revision history entry about floating point support 2020-01-21 03:29:49 +02:00
290761ec3d Move arm64/ppc64le/s390x jobs to the top; add C++14 to them; remove stray VARIANT=release 2020-01-13 19:43:11 +02:00
f143fe172d Fix conversion_test.cpp to not rely on BOOST_ENDIAN_BIG_BYTE 2020-01-13 19:41:04 +02:00
94bf4b41f4 Add more architectures to Travis 2020-01-13 17:16:17 +02:00
69c020ea8f Constrain the primary endian_reverse to not apply to class types; add test. Fixes #41. 2020-01-13 16:22:16 +02:00
3d053160ce Switch Travis to Xenial 2020-01-05 04:53:37 +02:00
3a50c15a97 Add CMake install support, tests 2020-01-05 03:29:05 +02:00
816c7597e3 Add order_test.cpp 2020-01-05 01:32:57 +02:00
7ac116915c __i386__ and __x86_64__ are little-endian (g++ 4.4 unfortunately has no other endianness macros) 2020-01-05 01:07:15 +02:00
1330d0f3c4 Add more macOS Travis jobs 2020-01-05 00:07:16 +02:00
7854cc109d Remove use of Predef in detail/order.hpp 2020-01-04 23:21:23 +02:00
1a8b6a498b Remove use of Predef in endian_test.cpp 2020-01-04 21:27:39 +02:00
b8139ad7a1 Remove use of Predef in arithmetic.hpp, buffers.hpp, conversion.hpp 2020-01-04 21:18:35 +02:00
3de20eb340 Merge pull request #38 from tanzislam/fix-macro-use-with-template-parameters
Fix BOOST_STATIC_ASSERT with template arguments
2019-10-25 14:06:07 -07:00
7f9a618b8c Fix BOOST_STATIC_ASSERT with template arguments
a2025a932 introduced a `BOOST_STATIC_ASSERT`-check with a template argument list. This causes a compilation error in a pre-C++11 compiler without support for variadic arguments (i.e. if `BOOST_NO_CXX11_VARIADIC_MACROS` is set).

For example:
    $ echo '#include <boost/endian/buffers.hpp>' > test.cpp
    $ g++ -c -std=c++03 -DBOOST_NO_CXX11_VARIADIC_MACROS -I/path/to/boost test.cpp

results in:

```
In file included from /path/to/boost/boost/endian/detail/endian_store.hpp:9,
                 from /path/to/boost/boost/endian/buffers.hpp:30,
                 from test.cpp:1:
/path/to/boost/boost/endian/detail/endian_reverse.hpp:111:76: error: macro "BOOST_STATIC_ASSERT" passed 2 arguments, but takes just 1
  111 |     BOOST_STATIC_ASSERT( is_integral<T>::value && !is_same<T, bool>::value );
      |                                                                            ^
In file included from /path/to/boost/boost/endian/detail/endian_reverse.hpp:13,
                 from /path/to/boost/boost/endian/detail/endian_store.hpp:9,
                 from /path/to/boost/boost/endian/buffers.hpp:30,
                 from test.cpp:1:
/path/to/boost/boost/static_assert.hpp:157: note: macro "BOOST_STATIC_ASSERT" defined here
  157 | #     define BOOST_STATIC_ASSERT( B ) \
      |
```
2019-10-25 15:18:24 +01:00
57d14c5cc5 Update revision history 2019-10-23 16:42:00 +03:00
c64f7c3372 Add <boost/endian.hpp> 2019-10-22 19:41:49 +03:00
fbc198e75d Add __int128 support to endian_reverse 2019-10-20 21:28:38 +03:00
b2faa783ad Update documentation for data() 2019-10-16 00:20:58 +03:00
51f095f019 Add data_test 2019-10-15 21:07:40 +03:00
59097ada36 Change data() to return unsigned char*; add non-const versions 2019-10-15 18:58:48 +03:00
52 changed files with 2503 additions and 821 deletions

194
.drone.jsonnet Normal file
View 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
View 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
View 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
View 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

View File

@ -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:

View File

@ -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
View File

@ -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
View 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).

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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}

View File

@ -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`

View File

@ -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

View File

@ -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
View 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.

View File

@ -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.

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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 )
{

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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
View 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()

View File

@ -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 ;

View 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();
}

View File

@ -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>

View 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>)

View File

@ -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

View File

@ -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
View 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();
}

View File

@ -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
View 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();
}

View File

@ -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();
}
}

View File

@ -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();
}

View 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();
}

View 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();
}

View 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();
}

View 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();
}

View File

@ -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;
}
}

View File

@ -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 );
}

View File

@ -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 );

View 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
View 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();
}

View 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

View 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

View File

@ -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;
}
};