diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000..e2262ca --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,370 @@ +# Copyright 2022 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +local library = "core"; + +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 16.04 GCC 5* 32/64", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 6 32/64", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14', ADDRMD: '32,64' }, + "g++-6-multilib", + ), + + linux_pipeline( + "Linux 18.04 GCC 7* 32/64", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32,64' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 8 32/64", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11,14,17', ADDRMD: '32,64' }, + "g++-8-multilib", + ), + + linux_pipeline( + "Linux 20.04 GCC 9* 32/64", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' }, + ), + + linux_pipeline( + "Linux 20.04 GCC 9* ARM64", + "cppalliance/droneubuntu2004:multiarch", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a' }, + arch="arm64", + ), + + linux_pipeline( + "Linux 20.04 GCC 9* S390x", + "cppalliance/droneubuntu2004:multiarch", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a' }, + arch="s390x", + ), + + linux_pipeline( + "Linux 20.04 GCC 10 32/64", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '03,11,14,17,20', ADDRMD: '32,64' }, + "g++-10-multilib", + ), + + linux_pipeline( + "Linux 22.04 GCC 11* 32/64", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32,64' }, + ), + + linux_pipeline( + "Linux 22.04 GCC 12 32 ASAN", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14,17,20,2b', 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,2b', ADDRMD: '64' } + asan, + "g++-12-multilib", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.5", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '03,11' }, + "clang-3.5", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.6", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '03,11,14' }, + "clang-3.6", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.7", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '03,11,14' }, + "clang-3.7", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.8", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '03,11,14' }, + "clang-3.8", + ), + + linux_pipeline( + "Linux 18.04 Clang 3.9", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '03,11,14' }, + "clang-3.9", + ), + + linux_pipeline( + "Linux 18.04 Clang 4.0", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '03,11,14' }, + "clang-4.0", + ), + + linux_pipeline( + "Linux 18.04 Clang 5.0", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '03,11,14,1z' }, + "clang-5.0", + ), + + linux_pipeline( + "Linux 18.04 Clang 6.0", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '03,11,14,17' }, + "clang-6.0", + ), + + linux_pipeline( + "Linux 20.04 Clang 7", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '03,11,14,17' }, + "clang-7", + ), + + linux_pipeline( + "Linux 20.04 Clang 8", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '03,11,14,17' }, + "clang-8", + ), + + linux_pipeline( + "Linux 20.04 Clang 9", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '03,11,14,17,2a' }, + "clang-9", + ), + + linux_pipeline( + "Linux 20.04 Clang 10", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '03,11,14,17,2a' }, + "clang-10", + ), + + linux_pipeline( + "Linux 20.04 Clang 11", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '03,11,14,17,2a' }, + "clang-11", + ), + + linux_pipeline( + "Linux 20.04 Clang 12", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '03,11,14,17,2a' }, + "clang-12", + ), + + linux_pipeline( + "Linux 22.04 Clang 13", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '03,11,14,17,20' }, + "clang-13", + ), + + linux_pipeline( + "Linux 22.04 Clang 14 UBSAN", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20,2b' } + 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,2b' } + asan, + "clang-14", + ), + + linux_pipeline( + "Linux 22.04 Clang 15", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '03,11,14,17,20,2b' }, + "clang-15", + ["deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"], + ), + + 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 VS2015 msvc-14.0", + "cppalliance/dronevs2015", + { TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' }, + ), + + windows_pipeline( + "Windows VS2017 msvc-14.1", + "cppalliance/dronevs2017", + { TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' }, + ), + + windows_pipeline( + "Windows VS2019 msvc-14.2", + "cppalliance/dronevs2019", + { TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' }, + ), + + windows_pipeline( + "Windows VS2022 msvc-14.3", + "cppalliance/dronevs2022:1", + { TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' }, + ), +] diff --git a/.drone/drone.bat b/.drone/drone.bat new file mode 100644 index 0000000..f06b052 --- /dev/null +++ b/.drone/drone.bat @@ -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 -I examples %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 diff --git a/.drone/drone.sh b/.drone/drone.sh new file mode 100755 index 0000000..622fbfe --- /dev/null +++ b/.drone/drone.sh @@ -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 -I examples $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} diff --git a/doc/alignof.qbk b/doc/alignof.qbk new file mode 100644 index 0000000..13a12f0 --- /dev/null +++ b/doc/alignof.qbk @@ -0,0 +1,33 @@ +[/ + Copyright 2023 Peter Dimov + Distributed under the Boost Software License, Version 1.0. + https://boost.org/LICENSE_1_0.txt +] + +[section:alignof alignof] + +[simplesect Authors] + +* Peter Dimov + +[endsimplesect] + +[section Header ] + +The header `` defines the macro `BOOST_CORE_ALIGNOF`, +a portable equivalent of the `alignof` operator from C++11. + +[section Example] + +`` +#include +#include + +constexpr std::size_t alignment_of_double = BOOST_CORE_ALIGNOF(double); +`` + +[endsect] + +[endsect] + +[endsect] diff --git a/doc/changes.qbk b/doc/changes.qbk index a519e42..3a63779 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -17,6 +17,7 @@ * Marked `boost::ref` member functions and associated methods with `noexcept`. * Marked `boost::swap` function with `noexcept`, depending on whether the type supports a non-throwing swap operation. * Added `boost::core::launder`, a portable implementation of `std::launder`. +* Added `BOOST_CORE_ALIGNOF`, a portable implementation of `alignof`. * Added `boost::core::max_align_t`, a portable equivalent of `std::max_align_t`, and `boost::core::max_align`, the alignment of `max_align_t`. diff --git a/doc/core.qbk b/doc/core.qbk index 6f3685e..57e0eb0 100644 --- a/doc/core.qbk +++ b/doc/core.qbk @@ -41,6 +41,7 @@ criteria for inclusion is that the utility component be: [include changes.qbk] [include addressof.qbk] +[include alignof.qbk] [include allocator_access.qbk] [include allocator_traits.qbk] [include bit.qbk] diff --git a/include/boost/core/alignof.hpp b/include/boost/core/alignof.hpp new file mode 100644 index 0000000..de1f01c --- /dev/null +++ b/include/boost/core/alignof.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_CORE_MAX_ALIGN_HPP_INCLUDED +#define BOOST_CORE_MAX_ALIGN_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if !defined(BOOST_NO_CXX11_ALIGNOF) + +#define BOOST_CORE_ALIGNOF alignof + +#elif defined(__GNUC__) + +#define BOOST_CORE_ALIGNOF __alignof__ + +#elif defined(_MSC_VER) + +#define BOOST_CORE_ALIGNOF __alignof + +#else + +namespace boost +{ +namespace core +{ +namespace detail +{ + +template struct alignof_helper +{ + char x; + T t; +}; + +} // namespace detail +} // namespace core +} // namespace boost + +#if defined(__GNUC__) +// ignoring -Wvariadic-macros with #pragma doesn't work under GCC +# pragma GCC system_header +#endif + +#define BOOST_CORE_ALIGNOF(...) offsetof( ::boost::core::detail::alignof_helper<__VA_ARGS__>, t ); + +#endif + +#endif // #ifndef BOOST_CORE_MAX_ALIGN_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index cbfbac0..b27fa97 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -354,6 +354,7 @@ run-fail verbose_terminate_handler_fail.cpp : : : off run launder_test.cpp ; +run alignof_test.cpp ; run max_align_test.cpp ; use-project /boost/core/swap : ./swap ; diff --git a/test/alignof_test.cpp b/test/alignof_test.cpp new file mode 100644 index 0000000..6468a79 --- /dev/null +++ b/test/alignof_test.cpp @@ -0,0 +1,98 @@ +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +template struct struct_of +{ + T t; +}; + +template union union_of +{ + T t; +}; + +template void test2() +{ + BOOST_TEST_EQ( BOOST_CORE_ALIGNOF(T), boost::alignment_of::value ); + +#if !defined(BOOST_NO_CXX11_ALIGNOF) + + BOOST_TEST_EQ( BOOST_CORE_ALIGNOF(T), alignof(T) ); + +#endif +} + +template void test() +{ + test2(); + test2(); + test2< struct_of >(); + test2< union_of >(); +} + +struct X +{ +}; + +int main() +{ + test(); + test(); + test(); + test(); + +#if !defined(BOOST_NO_LONG_LONG) +# if !( defined(__GNUC__) && defined(__i386__) ) + + // g++ -m32 has alignof(long long) = 8, but boost::alignment_of::value = 4 + test(); + +# endif +#endif + +#if defined(BOOST_HAS_INT128) + + test(); + +#endif + + test(); + +#if !( defined(__GNUC__) && defined(__i386__) ) + + // g++ -m32 has alignof(double) = 8, but boost::alignment_of::value = 4 + test(); + +#endif + + test(); + +#if defined(BOOST_HAS_FLOAT128) + + test<__float128>(); + +#endif + + test(); + test(); + +#if !defined(_MSC_VER) + + // under MSVC, alignof is 8, boost::alignment_of is 4 + // under clang-cl, alignof is 4, boost::alignment_of is 8 (!) + + test(); + +#endif + + test(); + + return boost::report_errors(); +} diff --git a/test/alloc_construct_cxx11_test.cpp b/test/alloc_construct_cxx11_test.cpp index 928cec8..2a5c86e 100644 --- a/test/alloc_construct_cxx11_test.cpp +++ b/test/alloc_construct_cxx11_test.cpp @@ -72,6 +72,7 @@ int main() BOOST_TEST_EQ(p->value(), 2); boost::alloc_destroy(a, p); BOOST_TEST_EQ(type::count, 0); + a.deallocate(p, 1); return boost::report_errors(); } #else