diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 00000000..afbe6484 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,435 @@ +# Copyright 2022 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +local library = "array"; + +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', + 'uname -a', + 'echo $DRONE_STAGE_MACHINE', + ] + + (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 16.04 GCC 4.6", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98' }, + "g++-4.6", + [ "ppa:ubuntu-toolchain-r/test" ], + ), + + linux_pipeline( + "Linux 16.04 GCC 4.7", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98' }, + "g++-4.7", + ), + + linux_pipeline( + "Linux 16.04 GCC 4.8", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '03,11' }, + "g++-4.8", + ), + + linux_pipeline( + "Linux 16.04 GCC 4.9", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11' }, + "g++-4.9", + ), + + linux_pipeline( + "Linux 16.04 GCC 5*", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 6", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '03,11,14' }, + "g++-6", + ), + + 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", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '03,11,14,17' }, + "g++-8", + ), + + 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/64", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' }, + "g++-12-multilib", + ), + + linux_pipeline( + "Linux 24.04 GCC 13 32/64 UBSAN", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' } + ubsan, + "g++-13-multilib", + ), + + linux_pipeline( + "Linux 24.04 GCC 14 32/64 ASAN", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' } + asan, + "g++-14-multilib", + ), + + linux_pipeline( + "Linux 25.10 GCC 15 32/64", + "cppalliance/droneubuntu2510:1", + { TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '11,14,17,20,23,2c', ADDRMD: '32,64' }, + "g++-15-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", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '03,11,14,17,20' }, + "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", + ), + + linux_pipeline( + "Linux 24.04 Clang 16", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '03,11,14,17,20,2b' }, + "clang-16", + ), + + linux_pipeline( + "Linux 24.04 Clang 17", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' }, + "clang-17", + ), + + linux_pipeline( + "Linux 24.04 Clang 18", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' }, + "clang-18", + ), + + linux_pipeline( + "Linux 24.04 Clang 19", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' }, + "clang-18", + ), + + linux_pipeline( + "Linux 24.04 Clang 20 UBSAN", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '03,11,14,17,20,2b' } + ubsan, + "clang-20", + ), + + linux_pipeline( + "Linux 24.04 Clang 20 ASAN", + "cppalliance/droneubuntu2404:1", + { TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '03,11,14,17,20,2b' } + asan, + "clang-20", + ), + + linux_pipeline( + "Linux 25.10 Clang 21", + "cppalliance/droneubuntu2510:1", + { TOOLSET: 'clang', COMPILER: 'clang++-21', CXXSTD: '03,11,14,17,20,23,2c' }, + "clang-21", + ), + + 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, + ), + + macos_pipeline( + "MacOS 12.4 Xcode 13.4.1 UBSAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + ubsan, + xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64", + ), + + macos_pipeline( + "MacOS 12.4 Xcode 13.4.1 ASAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + asan, + xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64", + ), + + windows_pipeline( + "Windows VS2015 msvc-14.0", + "cppalliance/dronevs2015", + { TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' }, + ), + + 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' }, + ), + + windows_pipeline( + "Windows VS2026 msvc-14.5", + "cppalliance/dronevs2026:1", + { TOOLSET: 'msvc-14.5', CXXSTD: '14,17,20,latest' }, + ), +] diff --git a/.drone.star b/.drone.star deleted file mode 100644 index 477c6c5c..00000000 --- a/.drone.star +++ /dev/null @@ -1,37 +0,0 @@ -# Use, modification, and distribution are -# subject to the Boost Software License, Version 1.0. (See accompanying -# file LICENSE.txt) -# -# Copyright Rene Rivera 2020. - -# For Drone CI we use the Starlark scripting language to reduce duplication. -# As the yaml syntax for Drone CI is rather limited. -# -# -globalenv={} -linuxglobalimage="cppalliance/droneubuntu1604:1" -windowsglobalimage="cppalliance/dronevs2019" - -def main(ctx): - return [ - linux_cxx("TEST_CMAKE=TRUE Job 0", "g++", packages="", buildtype="96ad197d74-2319b6d45f", image=linuxglobalimage, environment={'TEST_CMAKE': 'TRUE', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++ CXXSTD=03,11 Job 1", "g++", packages="", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 Job 2", "g++-4.7", packages="g++-4.7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.7', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11 Job 3", "g++-4.8", packages="g++-4.8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.8', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11 Job 4", "g++-4.9", packages="g++-4.9", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.9', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z Job 5", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z Job 6", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 Job 7", "g++-7", packages="g++-7", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '03,11,14,17', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 Job 8", "clang++", packages="", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03, Job 9", "clang++", packages="clang-3.5 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03, Job 10", "clang++", packages="clang-3.6", llvm_os="precise", llvm_ver="3.6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03, Job 11", "clang++", packages="clang-3.7", llvm_os="precise", llvm_ver="3.7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.7', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03, Job 12", "clang++-3.8", packages="clang-3.8 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.8', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03, Job 13", "clang++-3.9", packages="clang-3.9 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.9", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.9', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03, Job 14", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03, Job 15", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,1 Job 16", "clang++", packages="", buildtype="boost", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '1574bddb75'}, globalenv=globalenv), - ] - -# from https://github.com/boostorg/boost-ci -load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/.drone/96ad197d74-2319b6d45f.sh b/.drone/96ad197d74-2319b6d45f.sh deleted file mode 100755 index bdc59171..00000000 --- a/.drone/96ad197d74-2319b6d45f.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -set -ex -export TRAVIS_BUILD_DIR=$(pwd) -export DRONE_BUILD_DIR=$(pwd) -export TRAVIS_BRANCH=$DRONE_BRANCH -export VCS_COMMIT_ID=$DRONE_COMMIT -export GIT_COMMIT=$DRONE_COMMIT -export REPO_NAME=$DRONE_REPO -export PATH=~/.local/bin:/usr/local/bin:$PATH - -echo '==================================> BEFORE_INSTALL' - -. .drone/before-install.sh - -echo '==================================> INSTALL' - -BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/assert.git ../assert -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/config.git ../config -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/core.git ../core -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/static_assert.git ../static_assert -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/throw_exception.git ../throw_exception - -echo '==================================> BEFORE_SCRIPT' - -. $DRONE_BUILD_DIR/.drone/before-script.sh - -echo '==================================> SCRIPT' - -mkdir __build__ && cd __build__ -cmake ../test/test_cmake -cmake --build . - -echo '==================================> AFTER_SUCCESS' - -. $DRONE_BUILD_DIR/.drone/after-success.sh diff --git a/.drone/after-success.sh b/.drone/after-success.sh deleted file mode 100755 index 7a693aac..00000000 --- a/.drone/after-success.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - - diff --git a/.drone/before-install.sh b/.drone/before-install.sh deleted file mode 100755 index 7a693aac..00000000 --- a/.drone/before-install.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - - diff --git a/.drone/before-script.sh b/.drone/before-script.sh deleted file mode 100755 index 7a693aac..00000000 --- a/.drone/before-script.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - - diff --git a/.drone/boost.sh b/.drone/boost.sh deleted file mode 100755 index 144ed057..00000000 --- a/.drone/boost.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -set -ex -export TRAVIS_BUILD_DIR=$(pwd) -export DRONE_BUILD_DIR=$(pwd) -export TRAVIS_BRANCH=$DRONE_BRANCH -export VCS_COMMIT_ID=$DRONE_COMMIT -export GIT_COMMIT=$DRONE_COMMIT -export REPO_NAME=$DRONE_REPO -export PATH=~/.local/bin:/usr/local/bin:$PATH - -echo '==================================> BEFORE_INSTALL' - -. .drone/before-install.sh - -echo '==================================> INSTALL' - -BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true -cd .. -git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root -cd boost-root -git submodule update --init tools/build -git submodule update --init libs/config -git submodule update --init tools/boostdep -cp -r $TRAVIS_BUILD_DIR/* libs/array -python tools/boostdep/depinst/depinst.py array -./bootstrap.sh -./b2 headers - -echo '==================================> BEFORE_SCRIPT' - -. $DRONE_BUILD_DIR/.drone/before-script.sh - -echo '==================================> SCRIPT' - -echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam -./b2 -j 3 libs/array/test toolset=$TOOLSET cxxstd=$CXXSTD - -echo '==================================> AFTER_SUCCESS' - -. $DRONE_BUILD_DIR/.drone/after-success.sh diff --git a/.drone/drone.bat b/.drone/drone.bat new file mode 100644 index 00000000..66aaf78d --- /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 %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 00000000..2f2125df --- /dev/null +++ b/.drone/drone.sh @@ -0,0 +1,25 @@ +#!/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 +export PATH=~/.local/bin:/usr/local/bin:$PATH + +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} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d132519a..efee5447 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,177 +19,233 @@ jobs: include: - toolset: gcc-4.8 cxxstd: "03,11" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: g++-4.8-multilib address-model: 32,64 - toolset: gcc-4.9 cxxstd: "03,11" - os: ubuntu-latest container: ubuntu:16.04 + os: ubuntu-latest install: g++-4.9-multilib address-model: 32,64 - toolset: gcc-5 cxxstd: "03,11,14,1z" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: g++-5-multilib address-model: 32,64 - toolset: gcc-6 cxxstd: "03,11,14,1z" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: g++-6-multilib address-model: 32,64 - toolset: gcc-7 cxxstd: "03,11,14,17" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: g++-7-multilib address-model: 32,64 - toolset: gcc-8 cxxstd: "03,11,14,17,2a" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: g++-8-multilib address-model: 32,64 - toolset: gcc-9 cxxstd: "03,11,14,17,2a" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: g++-9-multilib address-model: 32,64 - toolset: gcc-10 cxxstd: "03,11,14,17,2a" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: g++-10-multilib address-model: 32,64 - toolset: gcc-11 cxxstd: "03,11,14,17,20" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: g++-11-multilib address-model: 32,64 - toolset: gcc-12 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: g++-12-multilib address-model: 32,64 - toolset: gcc-13 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-24.04 + container: ubuntu:24.04 + os: ubuntu-latest install: g++-13-multilib address-model: 32,64 - toolset: gcc-14 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-24.04 + container: ubuntu:24.04 + os: ubuntu-latest install: g++-14-multilib address-model: 32,64 + - toolset: gcc-15 + cxxstd: "03,11,14,17,20,23,2c" + container: ubuntu:25.10 + os: ubuntu-latest + install: g++-15-multilib + address-model: 32,64 - toolset: clang compiler: clang++-3.9 cxxstd: "03,11,14" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: clang-3.9 - toolset: clang compiler: clang++-4.0 cxxstd: "03,11,14" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: clang-4.0 - toolset: clang compiler: clang++-5.0 cxxstd: "03,11,14,1z" - os: ubuntu-latest container: ubuntu:18.04 + os: ubuntu-latest install: clang-5.0 - toolset: clang compiler: clang++-6.0 cxxstd: "03,11,14,17" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: clang-6.0 - toolset: clang compiler: clang++-7 cxxstd: "03,11,14,17" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: clang-7 - toolset: clang compiler: clang++-8 cxxstd: "03,11,14,17" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: clang-8 - toolset: clang compiler: clang++-9 cxxstd: "03,11,14,17,2a" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest install: clang-9 - toolset: clang compiler: clang++-10 cxxstd: "03,11,14,17,2a" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest + install: clang-10 - toolset: clang compiler: clang++-11 cxxstd: "03,11,14,17,2a" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest + install: clang-11 - toolset: clang compiler: clang++-12 cxxstd: "03,11,14,17,20" - os: ubuntu-20.04 + container: ubuntu:20.04 + os: ubuntu-latest + install: clang-12 - toolset: clang compiler: clang++-13 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-13 - toolset: clang compiler: clang++-14 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-14 - toolset: clang compiler: clang++-15 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-15 - toolset: clang compiler: clang++-16 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-24.04 + container: ubuntu:24.04 + os: ubuntu-latest install: clang-16 - toolset: clang compiler: clang++-17 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-24.04 + container: ubuntu:24.04 + os: ubuntu-latest install: clang-17 - toolset: clang compiler: clang++-18 cxxstd: "03,11,14,17,20,2b" - os: ubuntu-24.04 + container: ubuntu:24.04 + os: ubuntu-latest install: clang-18 - toolset: clang + compiler: clang++-19 cxxstd: "03,11,14,17,20,2b" - os: macos-13 + container: ubuntu:24.04 + os: ubuntu-latest + install: clang-19 + - toolset: clang + compiler: clang++-20 + cxxstd: "03,11,14,17,20,2b" + container: ubuntu:24.04 + os: ubuntu-latest + install: clang-20 + - toolset: clang + compiler: clang++-21 + cxxstd: "03,11,14,17,20,23,2c" + container: ubuntu:25.10 + os: ubuntu-latest + install: clang-21 - toolset: clang cxxstd: "03,11,14,17,20,2b" os: macos-14 - toolset: clang cxxstd: "03,11,14,17,20,2b" os: macos-15 + - toolset: clang + cxxstd: "03,11,14,17,20,23,2c" + os: macos-26 runs-on: ${{matrix.os}} - container: ${{matrix.container}} + + container: + image: ${{matrix.container}} + volumes: + - /node20217:/node20217:rw,rshared + - ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }} defaults: run: shell: bash steps: - - name: Enable Node 16 - run: | - echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV - - - uses: actions/checkout@v3 - - name: Setup container environment if: matrix.container run: | apt-get update - apt-get -y install sudo python3 git g++ + apt-get -y install sudo python3 git g++ curl xz-utils + + - name: Install nodejs20glibc2.17 + if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }} + run: | + curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz + tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217 + ldd /__e/node20/bin/node + + - uses: actions/checkout@v4 - name: Install packages if: matrix.install @@ -235,26 +291,18 @@ jobs: 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" + cxxstd: "14,17,20,latest" addrmd: 32,64 - os: windows-2022 + os: windows-2025 - toolset: gcc cxxstd: "03,11,14,17,2a" addrmd: 64 - os: windows-2019 + os: windows-2022 runs-on: ${{matrix.os}} @@ -294,12 +342,8 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 - - os: ubuntu-22.04 - - os: ubuntu-24.04 - - os: macos-13 - - os: macos-14 - - os: macos-15 + - os: ubuntu-latest + - os: macos-latest runs-on: ${{matrix.os}} @@ -343,12 +387,8 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 - - os: ubuntu-22.04 - - os: ubuntu-24.04 - - os: macos-13 - - os: macos-14 - - os: macos-15 + - os: ubuntu-latest + - os: macos-latest runs-on: ${{matrix.os}} @@ -402,12 +442,8 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 - - os: ubuntu-22.04 - - os: ubuntu-24.04 - - os: macos-13 - - os: macos-14 - - os: macos-15 + - os: ubuntu-latest + - os: macos-latest runs-on: ${{matrix.os}} @@ -459,8 +495,7 @@ jobs: fail-fast: false matrix: include: - - os: windows-2019 - - os: windows-2022 + - os: windows-latest runs-on: ${{matrix.os}} @@ -508,8 +543,7 @@ jobs: fail-fast: false matrix: include: - - os: windows-2019 - - os: windows-2022 + - os: windows-latest runs-on: ${{matrix.os}} @@ -575,8 +609,7 @@ jobs: fail-fast: false matrix: include: - - os: windows-2019 - - os: windows-2022 + - os: windows-latest runs-on: ${{matrix.os}} diff --git a/.travis.yml b/.travis.yml index f397fc54..f85958c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,6 @@ matrix: - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/assert.git ../assert - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/config.git ../config - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/core.git ../core - - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/static_assert.git ../static_assert - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/throw_exception.git ../throw_exception script: diff --git a/CMakeLists.txt b/CMakeLists.txt index 6727882e..343973a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,6 @@ target_link_libraries(boost_array INTERFACE Boost::assert Boost::config - Boost::core - Boost::static_assert Boost::throw_exception ) diff --git a/build.jam b/build.jam new file mode 100644 index 00000000..95e46155 --- /dev/null +++ b/build.jam @@ -0,0 +1,23 @@ +# Copyright 2023-2024 René Ferdinand Rivera Morell +# Copyright 2024 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +require-b2 5.2 ; + +constant boost_dependencies : + /boost/assert//boost_assert + /boost/config//boost_config + /boost/throw_exception//boost_throw_exception + ; + +project /boost/array ; + +explicit + [ alias boost_array : : : : include $(boost_dependencies) ] + [ alias all : boost_array test ] + ; + +call-if : boost-library array + ; + diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000..35b5e99a --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +/html diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index b7f51b71..83ce1dd2 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,19 +1,22 @@ #~ Copyright Marshall Clow 2013 +#~ Copyright Christian Mazakas 2024 #~ 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) -using boostbook ; +import asciidoctor ; -boostbook standalone - : array.xml - : boost.root=../../../.. ; +html array.html : array.adoc ; + +install html_ : array.html : html ; + +pdf array.pdf : array.adoc ; +explicit array.pdf ; + +install pdf_ : array.pdf : pdf ; +explicit pdf_ ; ############################################################################### -alias boostdoc - : array.xml - : - : - : ; +alias boostdoc ; explicit boostdoc ; -alias boostrelease ; +alias boostrelease : html_ ; explicit boostrelease ; diff --git a/doc/array.adoc b/doc/array.adoc new file mode 100644 index 00000000..a7e867d2 --- /dev/null +++ b/doc/array.adoc @@ -0,0 +1,28 @@ +//// +Copyright 2001-2004 Nicolai M. Josuttis +Copyright 2012 Marshall Clow +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +# Boost.Array +Nicolai M. Josuttis +:toc: left +:toclevels: 4 +:idprefix: +:docinfo: private-footer +:source-highlighter: rouge +:source-language: c++ +:sectanchors: + +:leveloffset: +1 + +include::array/introduction.adoc[] +include::array/changes.adoc[] +include::array/reference.adoc[] +include::array/design_rationale.adoc[] +include::array/information.adoc[] +include::array/copyright.adoc[] + +:leveloffset: -1 diff --git a/doc/array.xml b/doc/array.xml deleted file mode 100644 index 68ee5a31..00000000 --- a/doc/array.xml +++ /dev/null @@ -1,639 +0,0 @@ - - - - - - Nicolai - Josuttis - - - Marshall - Clow - - - - 2001 - 2002 - 2003 - 2004 - Nicolai M. Josuttis - - - - 2012 - Marshall Clow - - - - 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) - - - - STL compliant container wrapper for arrays of constant size - - - - Boost.Array - -
- Introduction - - - - - The C++ Standard Template Library STL as part of the C++ - Standard Library provides a framework for processing algorithms on - different kind of containers. However, ordinary arrays don't - provide the interface of STL containers (although, they provide - the iterator interface of STL containers). - - As replacement for ordinary arrays, the STL provides class - std::vector. However, - std::vector<> provides - the semantics of dynamic arrays. Thus, it manages data to be able - to change the number of elements. This results in some overhead in - case only arrays with static size are needed. - - In his book, Generic Programming and the - STL, Matthew H. Austern introduces a useful wrapper - class for ordinary arrays with static size, called - block. It is safer and has no worse performance than - ordinary arrays. In The C++ Programming - Language, 3rd edition, Bjarne Stroustrup introduces a - similar class, called c_array, which I (Nicolai Josuttis) present - slightly modified in my book The C++ Standard Library - - A Tutorial and Reference, called - carray. This is the essence of these approaches - spiced with many feedback from boost. - - After considering different names, we decided to name this - class simply array. - - Note that this class is suggested to be part of the next - Technical Report, which will extend the C++ Standard (see - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1548.htm). - - Update: std::array is (as of C++11) part of the C++ standard. - The differences between boost::array and std::array are minimal. - If you are using C++11, you should consider using std::array instead of boost::array. - - - Class array fulfills most - but not all of the requirements of "reversible containers" (see - Section 23.1, [lib.container.requirements] of the C++ - Standard). The reasons array is not an reversible STL container is - because: - - No constructors are provided. - Elements may have an undetermined initial value (see ). - swap() has no constant complexity. - size() is always constant, based on the second template argument of the type. - The container provides no allocator support. - - - - It doesn't fulfill the requirements of a "sequence" (see Section 23.1.1, [lib.sequence.reqmts] of the C++ Standard), except that: - - front() and back() are provided. - operator[] and at() are provided. - - -
- - -
- - - - - STL compliant container wrapper for arrays of constant size - - T - - - T* - - - const T* - - - std::reverse_iterator<iterator> - - - std::reverse_iterator<const_iterator> - - - T& - - - const T& - - - std::size_t - - - std::ptrdiff_t - - - - size_type - N - - - - - - const array<U, N>& - - std::copy(rhs.begin(),rhs.end(), begin()) - - - - - - iterator - - - const_iterator - - - iterator for the first element - will not throw - - - - - iterator - - - const_iterator - - - iterator for position after the last element - will not throw - - - - - const_iterator - - - constant iterator for the first element - will not throw - - - - - const_iterator - - - constant iterator for position after the last element - will not throw - - - - - - - reverse_iterator - - - const_reverse_iterator - - - reverse iterator for the first element of reverse iteration - - - - - reverse_iterator - - - const_reverse_iterator - - - reverse iterator for position after the last element in reverse iteration - - - - - const_reverse_iterator - - - constant reverse iterator for the first element of reverse iteration - will not throw - - - - - const_reverse_iterator - - - constant reverse iterator for position after the last element in reverse iteration - will not throw - - - - - - size_type - N - - - bool - N==0 - will not throw - - - size_type - N - will not throw - - - - - - - reference - - size_type - - - - - const_reference - - size_type - - - - i < N - element with index i - will not throw. - - - - - reference - - size_type - - - - - const_reference - - size_type - - - - element with index i - std::range_error if i >= N - - - - - reference - - - const_reference - - N > 0 - the first element - will not throw - - - - - reference - - - const_reference - - N > 0 - the last element - will not throw - - - - const T* - elems - will not throw - - - - T* - elems - will not throw - - - - - - void - - array<T, N>& - - std::swap_ranges(begin(), end(), other.begin()) - linear in N - - - void - - const T& - - std::fill_n(begin(), N, value) - - - - - T - - - - - - - void - - - array<T, N>& - - - array<T, N>& - - - x.swap(y) - will not throw. - - - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - std::equal(x.begin(), x.end(), y.begin()) - - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - !(x == y) - - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()) - - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - y < x - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - !(y < x) - - - - - - bool - - - const array<T, N>& - - - const array<T, N>& - - - !(x < y) - - - - - - - - T - - - array<T, N>& - - element of array with index Idx - Will static_assert if Idx >= N - - - - - - T - - - const array<T, N>& - - const element of array with index Idx - Will static_assert if Idx >= N - - - - - -
-
- -
- Design Rationale - - There was an important design tradeoff regarding the - constructors: We could implement array as an "aggregate" (see - Section 8.5.1, [dcl.init.aggr], of the C++ Standard). This would - mean: - - An array can be initialized with a - brace-enclosing, comma-separated list of initializers for the - elements of the container, written in increasing subscript - order: - - boost::array<int,4> a = { { 1, 2, 3 } }; - - Note that if there are fewer elements in the - initializer list, then each remaining element gets - default-initialized (thus, it has a defined value). - - - However, this approach has its drawbacks: passing no initializer list means that the elements - have an indetermined initial value, because the rule says - that aggregates may have: - - No user-declared constructors. - No private or protected non-static data members. - No base classes. - No virtual functions. - - - - Nevertheless, The current implementation uses this approach. - - Note that for standard conforming compilers it is possible to - use fewer braces (according to 8.5.1 (11) of the Standard). That is, - you can initialize an array as follows: - - -boost::array<int,4> a = { 1, 2, 3 }; - - - I'd appreciate any constructive feedback. Please note: I don't have time to read all boost - mails. Thus, to make sure that feedback arrives to me, please send - me a copy of each mail regarding this class. - - The code is provided "as is" without expressed or implied - warranty. - -
- -
- For more information... - To find more details about using ordinary arrays in C++ and - the framework of the STL, see e.g. - - The C++ Standard Library - A Tutorial and Reference -by Nicolai M. Josuttis -Addison Wesley Longman, 1999 -ISBN 0-201-37926-0 - - - Home Page of Nicolai - Josuttis -
- -
- Acknowledgements - - Doug Gregor ported the documentation to the BoostBook format. -
- - - -
diff --git a/doc/array/changes.adoc b/doc/array/changes.adoc new file mode 100644 index 00000000..8f10f4c2 --- /dev/null +++ b/doc/array/changes.adoc @@ -0,0 +1,24 @@ +//// +Copyright 2025 Peter Dimov +Distributed under the Boost Software License, Version 1.0. +http://www.boost.org/LICENSE_1_0.txt +//// + +[#changes] +# Revision History +:toc: +:toc-title: +:idprefix: + +## Changes in 1.88.0 + +* Converted documentation to AsciiDoc (Christian Mazakas). +* Added `noexcept` and `constexpr` as appropriate. +* Marked obsolete functions as deprecated. +* Removed obsolete compiler workarounds. +* Changed `array::begin()`, `cbegin()`, `end()`, `cend()` to return `nullptr`, enabling `constexpr`. + This matches the behavior of `std::array`. +* Removed local `hash_value` overload; `boost::hash` supports array-like types natively. +* `array` can now be initialized with `= {{}}`. +* Added `operator\<\=>`. +* Added `to_array`. diff --git a/doc/array/copyright.adoc b/doc/array/copyright.adoc new file mode 100644 index 00000000..ca1724cb --- /dev/null +++ b/doc/array/copyright.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#copyright] +# Copyright and License +:idprefix: copyright + +Copyright (C) 2001-2004 Nicolai M. Josuttis + +Copyright (C) 2012 Marshall Clow + +Distributed under the https://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. diff --git a/doc/array/design_rationale.adoc b/doc/array/design_rationale.adoc new file mode 100644 index 00000000..7a32d28b --- /dev/null +++ b/doc/array/design_rationale.adoc @@ -0,0 +1,39 @@ +//// +Copyright 2001-2004 Nicolai M. Josuttis +Copyright 2012 Marshall Clow +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#design] +# Design Rationale +:idprefix: design_ +:cpp: C++ + +There was an important design tradeoff regarding the constructors: We could implement array as an "aggregate" (see Section 8.5.1, [dcl.init.aggr], of the C++ Standard). This would mean: + +* An array can be initialized with a brace-enclosing, comma-separated list of initializers for the elements of the container, written in increasing subscript order: ++ +-- +```cpp +boost::array a = { { 1, 2, 3 } }; +``` + +Note that if there are fewer elements in the initializer list, then each remaining element gets default-initialized (thus, it has a defined value). +-- + +However, this approach has its drawbacks: **passing no initializer list means that the elements have an indetermined initial value**, because the rule says that aggregates may have: + +* No user-declared constructors. +* No private or protected non-static data members. +* No base classes. +* No virtual functions. + +Nevertheless, the current implementation uses this approach. + +Note that for standard conforming compilers it is possible to use fewer braces (according to 8.5.1 (11) of the Standard). That is, you can initialize an array as follows: + +```cpp +boost::array a = { 1, 2, 3 }; +``` diff --git a/doc/array/information.adoc b/doc/array/information.adoc new file mode 100644 index 00000000..ca8b1a86 --- /dev/null +++ b/doc/array/information.adoc @@ -0,0 +1,22 @@ +//// +Copyright 2001-2004 Nicolai M. Josuttis +Copyright 2012 Marshall Clow +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#information] +# For more information... +:idprefix: information_ +:cpp: C++ + +To find more details about using ordinary arrays in C++ and the framework of the STL, see e.g. + +The C++ Standard Library - A Tutorial and Reference + +by Nicolai M. Josuttis + +Addison Wesley Longman, 1999 + +ISBN 0-201-37926-0 + + +http://www.josuttis.com/[Home Page of Nicolai Josuttis] diff --git a/doc/array/introduction.adoc b/doc/array/introduction.adoc new file mode 100644 index 00000000..a334f0a2 --- /dev/null +++ b/doc/array/introduction.adoc @@ -0,0 +1,44 @@ +//// +Copyright 2001-2004 Nicolai M. Josuttis +Copyright 2012 Marshall Clow +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#introduction] +# Introduction +:idprefix: introduction_ +:cpp: C++ + +The {cpp} Standard Template Library STL as part of the {cpp} Standard Library provides a framework for processing algorithms on different kind of containers. +However, ordinary arrays don't provide the interface of STL containers (although, they provide the iterator interface of STL containers). + +As replacement for ordinary arrays, the STL provides class `std::vector`. +However, `std::vector<>` provides the semantics of dynamic arrays. +Thus, it manages data to be able to change the number of elements. +This results in some overhead in case only arrays with static size are needed. + +In his book, _Generic Programming and the STL_, Matthew H. Austern introduces a useful wrapper class for ordinary arrays with static size, called `block`. +It is safer and has no worse performance than ordinary arrays. +In _The {cpp} Programming Language_, 3rd edition, Bjarne Stroustrup introduces a similar class, called c_array, which I (http://www.josuttis.com/[Nicolai Josuttis]) present slightly modified in my book _The {cpp} Standard Library - A Tutorial and Reference_, called `carray`. +This is the essence of these approaches spiced with many feedback from https://www.boost.org/[Boost]. + +After considering different names, we decided to name this class simply `array`. + +Note that this class is suggested to be part of the next Technical Report, which will extend the {cpp} Standard (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1548.htm). + +Update: `std::array` is (as of {cpp}11) part of the {cpp} standard. The differences between `boost::array` and `std::array` are minimal. If you are using {cpp}11, you should consider using `std::array` instead of `boost::array`. + +Class `array` fulfills most but not all of the requirements of "reversible containers" (see Section 23.1, [lib.container.requirements] of the {cpp} Standard). The reasons array is not an reversible STL container is because: + +* No constructors are provided. +* Elements may have an undetermined initial value (see the <>). +* `swap()` has no constant complexity. +* `size()` is always constant, based on the second template argument of the type. +* The container provides no allocator support. + +It doesn't fulfill the requirements of a "sequence" (see Section 23.1.1, [lib.sequence.reqmts] of the {cpp} Standard), except that: + +* `front()` and `back()` are provided. +* `operator[]` and `at()` are provided. diff --git a/doc/array/reference.adoc b/doc/array/reference.adoc new file mode 100644 index 00000000..2639a8be --- /dev/null +++ b/doc/array/reference.adoc @@ -0,0 +1,452 @@ +//// +Copyright 2001-2004 Nicolai M. Josuttis +Copyright 2012 Marshall Clow +Copyright 2024 Christian Mazakas +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#reference] +# Reference +:idprefix: reference_ +:cpp: C++ + +## Header + +```cpp +namespace boost { + + template class array; + + template + void swap(array&, array&); + + template + constexpr bool operator==(const array&, const array&); + template + constexpr bool operator!=(const array&, const array&); + + template + constexpr bool operator<(const array&, const array&); + template + constexpr bool operator>(const array&, const array&); + template + constexpr bool operator<=(const array&, const array&); + template + constexpr bool operator>=(const array&, const array&); + + template + constexpr auto operator<=>(const array&, const array&); + + template + constexpr T& get(array&) noexcept; + template + constexpr const T& get(const array&) noexcept; + + template + constexpr array to_array( T const (&)[N] ); + template + constexpr array to_array( T (&&)[N] ); + template + constexpr array to_array( T const (&&)[N] ); +} +``` + +## Class template array + +### Synopsis + +```cpp +// In header: + +template +class array { +public: + + // types + + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // static constants + + static const size_type static_size = N; + + // construct/copy/destroy + + template array& operator=(const array&); + + // iterator support + + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr const_iterator cbegin() const noexcept; + + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cend() const noexcept; + + // reverse iterator support + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator crbegin() const noexcept; + + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity + + static constexpr size_type size() noexcept; + static constexpr bool empty() noexcept; + static constexpr size_type max_size() noexcept; + + // element access + + constexpr reference operator[](size_type); + constexpr const_reference operator[](size_type) const; + + constexpr reference at(size_type); + constexpr const_reference at(size_type) const; + + constexpr reference front(); + constexpr const_reference front() const; + + constexpr reference back(); + constexpr const_reference back() const; + + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + + T* c_array() noexcept; // deprecated + + // modifiers + + swap(array&); + + constexpr void fill(const T&); + void assign(const T&); // deprecated + + // public data members + T elems[N]; +}; +``` + +### Construct/Copy/Destroy + +``` +template array& operator=(const array& other); +``` +[horizontal] +Effects: :: For each `i` in `[0..N)`, performs `elems[i] = other.elems[i];`. + +--- + +### Iterator Support + +``` +constexpr iterator begin() noexcept; +constexpr const_iterator begin() const noexcept; +constexpr const_iterator cbegin() const noexcept; +``` +[horizontal] +Returns: :: `data()`. + +--- + +``` +constexpr iterator end() noexcept; +constexpr const_iterator end() const noexcept; +constexpr const_iterator cend() const noexcept; +``` +[horizontal] +Returns: :: `data() + size()`. + +--- + +### Reverse Iterator Support + +``` +reverse_iterator rbegin() noexcept; +``` +[horizontal] +Returns: :: `reverse_iterator(end())`. + +--- + +``` +const_reverse_iterator rbegin() const noexcept; +const_reverse_iterator crbegin() const noexcept; +``` +[horizontal] +Returns: :: `const_reverse_iterator(end())`. + +--- + +``` +reverse_iterator rend() noexcept; +``` +[horizontal] +Returns: :: `reverse_iterator(begin())`. + +--- + +``` +const_reverse_iterator rend() const noexcept; +const_reverse_iterator crend() const noexcept; +``` +[horizontal] +Returns: :: `const_reverse_iterator(begin())`. + +--- + +### Capacity + +``` +static constexpr size_type size() noexcept; +``` +[horizontal] +Returns: :: `N`. + +--- + +``` +static constexpr bool empty() noexcept; +``` +[horizontal] +Returns: :: `N == 0`. + +--- + +``` +static constexpr size_type max_size() noexcept; +``` +[horizontal] +Returns: :: `N`. + +--- + +### Element Access + +``` +constexpr reference operator[](size_type i); +constexpr const_reference operator[](size_type i) const; +``` +[horizontal] +Requires: :: `i < N`. +Returns: :: `elems[i]`. +Throws: :: Nothing. + +--- + +``` +constexpr reference at(size_type i); +constexpr const_reference at(size_type i) const; +``` +[horizontal] +Returns: :: `elems[i]`. +Throws: :: `std::out_of_range` if `i >= N`. + +--- + +``` +constexpr reference front(); +constexpr const_reference front() const; +``` +[horizontal] +Requires: :: `N > 0`. +Returns: :: `elems[0]`. +Throws: :: Nothing. + +--- + +``` +constexpr reference back(); +constexpr const_reference back() const; +``` +[horizontal] +Requires: :: `N > 0`. +Returns: :: `elems[N-1]`. +Throws: :: Nothing. + +--- + +``` +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +``` +[horizontal] +Returns: :: `elems`. + +--- + +``` +T* c_array() noexcept; // deprecated +``` +[horizontal] +Returns: :: `data()`. +Remarks: :: This function is deprecated. Use `data()` instead. + +--- + +### Modifiers + +``` +void swap(array& other); +``` +[horizontal] +Effects: :: `std::swap(elems, other.elems)`. +Complexity: :: linear in `N`. + +--- + +``` +void fill(const T& value); +``` +[horizontal] +Effects: :: For each `i` in `[0..N)`, performs `elems[i] = value;`. + +--- + +``` +void assign(const T& value); // deprecated +``` +[horizontal] +Effects: :: `fill(value)`. +Remarks: :: An obsolete and deprecated spelling of `fill`. Use `fill` instead. + +--- + +### Specialized Algorithms + +``` +template + void swap(array& x, array& y); +``` +[horizontal] +Effects: :: `x.swap(y)`. + +--- + +### Comparisons + +``` +template + constexpr bool operator==(const array& x, const array& y); +``` +[horizontal] +Returns: :: `std::equal(x.begin(), x.end(), y.begin())`. + +--- + +``` +template + constexpr bool operator!=(const array& x, const array& y); +``` +[horizontal] +Returns: :: `!(x == y)`. + +--- + +``` +template + constexpr bool operator<(const array& x, const array& y); +``` +[horizontal] +Returns: :: `std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end())`. + +--- + +``` +template + constexpr bool operator>(const array& x, const array& y); +``` +[horizontal] +Returns: :: `y < x`. + +--- + +``` +template + constexpr bool operator<=(const array& x, const array& y); +``` +[horizontal] +Returns: :: `!(y < x)`. + +--- + +``` +template + constexpr bool operator>=(const array& x, const array& y); +``` +[horizontal] +Returns: :: `!(x < y)`. + +--- + +``` +template + constexpr auto operator<=>(const array& x, const array& y) + -> decltype(x[0] <=> y[0]); +``` +[horizontal] +Effects: :: For each `i` in `[0..N)`, if `(x[i] \<\=> y[i]) != 0`, returns `x[i] \<\=> y[i]`. Otherwise, returns `std::strong_ordering::equal`, converted to the return type. +Remarks: :: When `N` is 0, the return type is `std::strong_ordering` and the return value is `std::strong_ordering::equal`. + +--- + +### Specializations + +``` +template + constexpr T& get(array& arr) noexcept; +``` +[horizontal] +Mandates: :: `Idx < N`. +Returns: :: `arr[Idx]`. + +--- + +``` +template + constexpr const T& get(const array& arr) noexcept; +``` +[horizontal] +Mandates: :: `Idx < N`. +Returns: :: `arr[Idx]`. + +--- + + +### Creation + +``` +template + constexpr array to_array( T const (&a)[N] ); +``` +[horizontal] +Returns: :: an `array` `r` such that for each `i` in `[0..N)`, `r[i]` is copied from `a[i]`. + +``` +template + constexpr array to_array( T (&&a)[N] ); +``` +[horizontal] +Returns: :: an `array` `r` such that for each `i` in `[0..N)`, `r[i]` is moved from `std::move(a[i])`. + +``` +template + constexpr array to_array( T const (&&a)[N] ); +``` +[horizontal] +Returns: :: an `array` `r` such that for each `i` in `[0..N)`, `r[i]` is copied from `a[i]`. + +--- diff --git a/include/boost/array.hpp b/include/boost/array.hpp index 02bd76db..bea6f981 100644 --- a/include/boost/array.hpp +++ b/include/boost/array.hpp @@ -1,3 +1,6 @@ +#ifndef BOOST_ARRAY_HPP_INCLUDED +#define BOOST_ARRAY_HPP_INCLUDED + /* The following code declares class array, * an STL container (as wrapper) for arrays of constant size. * @@ -28,31 +31,31 @@ * * Jan 29, 2004 */ -#ifndef BOOST_ARRAY_HPP -#define BOOST_ARRAY_HPP -#include +#include +#include #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) # pragma warning(push) -# pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe -# pragma warning(disable:4510) // boost::array' : default constructor could not be generated -# pragma warning(disable:4610) // warning C4610: class 'boost::array' can never be instantiated - user defined constructor required +# pragma warning(disable: 4510) // boost::array' : default constructor could not be generated +# pragma warning(disable: 4512) // boost::array' : assignment operator could not be generated +# pragma warning(disable: 4610) // class 'boost::array' can never be instantiated - user defined constructor required +# pragma warning(disable: 4702) // unreachable code #endif -#include -#include -#include #include -#include #include - #include -#include - -// FIXES for broken compilers -#include +#include +#include +#include +#include +#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L +# if __has_include() +# include +# endif +#endif namespace boost { @@ -72,62 +75,54 @@ namespace boost { typedef std::ptrdiff_t difference_type; // iterator support - iterator begin() { return elems; } - const_iterator begin() const { return elems; } - const_iterator cbegin() const { return elems; } + BOOST_CXX14_CONSTEXPR iterator begin() BOOST_NOEXCEPT { return elems; } + BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return elems; } + BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return elems; } - iterator end() { return elems+N; } - const_iterator end() const { return elems+N; } - const_iterator cend() const { return elems+N; } + BOOST_CXX14_CONSTEXPR iterator end() BOOST_NOEXCEPT { return elems+N; } + BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return elems+N; } + BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return elems+N; } // reverse iterator support -#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; -#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#else - // workaround for broken reverse_iterator implementations - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#endif - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { + reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const { + const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { + reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } + const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const { + const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } // operator[] - reference operator[](size_type i) + BOOST_CXX14_CONSTEXPR reference operator[](size_type i) { return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; } - /*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const +#if !BOOST_WORKAROUND(BOOST_GCC, < 50000) + BOOST_CONSTEXPR +#endif + const_reference operator[](size_type i) const { return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; } // at() with range check - reference at(size_type i) { return rangecheck(i), elems[i]; } - /*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; } + BOOST_CXX14_CONSTEXPR reference at(size_type i) { return rangecheck(i), elems[i]; } + BOOST_CONSTEXPR const_reference at(size_type i) const { return rangecheck(i), elems[i]; } // front() and back() - reference front() + BOOST_CXX14_CONSTEXPR reference front() { return elems[0]; } @@ -137,7 +132,7 @@ namespace boost { return elems[0]; } - reference back() + BOOST_CXX14_CONSTEXPR reference back() { return elems[N-1]; } @@ -148,38 +143,56 @@ namespace boost { } // size is constant - static BOOST_CONSTEXPR size_type size() { return N; } - static BOOST_CONSTEXPR bool empty() { return false; } - static BOOST_CONSTEXPR size_type max_size() { return N; } + static BOOST_CONSTEXPR size_type size() BOOST_NOEXCEPT { return N; } + static BOOST_CONSTEXPR bool empty() BOOST_NOEXCEPT { return false; } + static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return N; } enum { static_size = N }; // swap (note: linear complexity) - void swap (array& y) { - for (size_type i = 0; i < N; ++i) - boost::core::invoke_swap(elems[i],y.elems[i]); + BOOST_CXX14_CONSTEXPR void swap (array& y) + { + std::swap( elems, y.elems ); } - // direct access to data (read-only) - const T* data() const { return elems; } - T* data() { return elems; } + // direct access to data + BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return elems; } + BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return elems; } - // use array as C array (direct read/write access to data) - T* c_array() { return elems; } + // obsolete + BOOST_DEPRECATED( "please use `data()` instead" ) + T* c_array() BOOST_NOEXCEPT { return elems; } // assignment with type conversion template - array& operator= (const array& rhs) { - std::copy(rhs.begin(),rhs.end(), begin()); + array& operator= (const array& rhs) + { + for( std::size_t i = 0; i < N; ++i ) + { + elems[ i ] = rhs.elems[ i ]; + } + return *this; } - // assign one value to all elements - void assign (const T& value) { fill ( value ); } // A synonym for fill - void fill (const T& value) + // fill with one value + BOOST_CXX14_CONSTEXPR void fill (const T& value) { - std::fill_n(begin(),size(),value); + // using elems[ 0 ] as a temporary copy + // avoids the aliasing opportunity betw. + // `value` and `elems` + + elems[ 0 ] = value; + + for( std::size_t i = 1; i < N; ++i ) + { + elems[ i ] = elems[ 0 ]; + } } + // an obsolete synonym for fill + BOOST_DEPRECATED( "please use `fill` instead" ) + void assign (const T& value) { fill ( value ); } + // check range (may be private because it is static) static BOOST_CONSTEXPR bool rangecheck (size_type i) { return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; @@ -189,6 +202,8 @@ namespace boost { template< class T > class array< T, 0 > { + public: + struct {} elems; // enables initialization with = {{}} public: // type definitions @@ -201,42 +216,31 @@ namespace boost { typedef std::ptrdiff_t difference_type; // iterator support - iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } - const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } - const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + BOOST_CXX14_CONSTEXPR iterator begin() BOOST_NOEXCEPT { return data(); } + BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return data(); } + BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return data(); } - iterator end() { return begin(); } - const_iterator end() const { return begin(); } - const_iterator cend() const { return cbegin(); } + BOOST_CXX14_CONSTEXPR iterator end() BOOST_NOEXCEPT { return begin(); } + BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return begin(); } + BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return cbegin(); } // reverse iterator support -#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; -#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#else - // workaround for broken reverse_iterator implementations - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#endif - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { + reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const { + const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { + reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } + const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const { + const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } @@ -246,14 +250,14 @@ namespace boost { return failed_rangecheck(); } - /*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const + const_reference operator[](size_type /*i*/) const { return failed_rangecheck(); } // at() with range check - reference at(size_type /*i*/) { return failed_rangecheck(); } - /*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); } + reference at(size_type /*i*/) { return failed_rangecheck(); } + const_reference at(size_type /*i*/) const { return failed_rangecheck(); } // front() and back() reference front() @@ -261,7 +265,7 @@ namespace boost { return failed_rangecheck(); } - BOOST_CONSTEXPR const_reference front() const + const_reference front() const { return failed_rangecheck(); } @@ -271,26 +275,28 @@ namespace boost { return failed_rangecheck(); } - BOOST_CONSTEXPR const_reference back() const + const_reference back() const { return failed_rangecheck(); } // size is constant - static BOOST_CONSTEXPR size_type size() { return 0; } - static BOOST_CONSTEXPR bool empty() { return true; } - static BOOST_CONSTEXPR size_type max_size() { return 0; } + static BOOST_CONSTEXPR size_type size() BOOST_NOEXCEPT { return 0; } + static BOOST_CONSTEXPR bool empty() BOOST_NOEXCEPT { return true; } + static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return 0; } enum { static_size = 0 }; - void swap (array& /*y*/) { + BOOST_CXX14_CONSTEXPR void swap (array& /*y*/) + { } - // direct access to data (read-only) - const T* data() const { return 0; } - T* data() { return 0; } + // direct access to data + BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return 0; } + BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return 0; } - // use array as C array (direct read/write access to data) - T* c_array() { return 0; } + // obsolete + BOOST_DEPRECATED( "please use `data()` instead" ) + T* c_array() BOOST_NOEXCEPT { return 0; } // assignment with type conversion template @@ -298,87 +304,119 @@ namespace boost { return *this; } - // assign one value to all elements + // an obsolete synonym for fill + BOOST_DEPRECATED( "please use `fill` instead" ) void assign (const T& value) { fill ( value ); } - void fill (const T& ) {} + + // fill with one value + BOOST_CXX14_CONSTEXPR void fill (const T& ) {} // check range (may be private because it is static) - static reference failed_rangecheck () { - std::out_of_range e("attempt to access element of an empty array"); - boost::throw_exception(e); -#if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__)) - // - // We need to return something here to keep - // some compilers happy: however we will never - // actually get here.... - // - static T placeholder; - return placeholder; -#endif - } + static reference failed_rangecheck () + { + boost::throw_exception( std::out_of_range( "attempt to access element of an empty array" ) ); + } }; // comparisons template - bool operator== (const array& x, const array& y) { - return std::equal(x.begin(), x.end(), y.begin()); + BOOST_CXX14_CONSTEXPR bool operator== (const array& x, const array& y) + { + for( std::size_t i = 0; i < N; ++i ) + { + if( !( x[ i ] == y[ i ] ) ) return false; + } + + return true; } - template - bool operator< (const array& x, const array& y) { - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); + +#if BOOST_WORKAROUND(BOOST_GCC, < 90000) + + template + BOOST_CXX14_CONSTEXPR bool operator== (const array& /*x*/, const array& /*y*/) + { + return true; } + +#endif + template - bool operator!= (const array& x, const array& y) { + BOOST_CXX14_CONSTEXPR bool operator!= (const array& x, const array& y) { return !(x==y); } + + template + BOOST_CXX14_CONSTEXPR bool operator< (const array& x, const array& y) + { + for( std::size_t i = 0; i < N; ++i ) + { + if( x[ i ] < y[ i ] ) return true; + if( y[ i ] < x[ i ] ) return false; + } + + return false; + } + +#if BOOST_WORKAROUND(BOOST_GCC, < 90000) + + template + BOOST_CXX14_CONSTEXPR bool operator< (const array& /*x*/, const array& /*y*/) + { + return false; + } + +#endif + template - bool operator> (const array& x, const array& y) { + BOOST_CXX14_CONSTEXPR bool operator> (const array& x, const array& y) { return y - bool operator<= (const array& x, const array& y) { + BOOST_CXX14_CONSTEXPR bool operator<= (const array& x, const array& y) { return !(y - bool operator>= (const array& x, const array& y) { + BOOST_CXX14_CONSTEXPR bool operator>= (const array& x, const array& y) { return !(x - inline void swap (array& x, array& y) { + BOOST_CXX14_CONSTEXPR inline void swap (array& x, array& y) { x.swap(y); } -#if defined(__SUNPRO_CC) -// Trac ticket #4757; the Sun Solaris compiler can't handle -// syntax like 'T(&get_c_array(boost::array& arg))[N]' -// -// We can't just use this for all compilers, because the -// borland compilers can't handle this form. - namespace detail { - template struct c_array - { - typedef T type[N]; - }; +#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L +# if __has_include() + + template + constexpr auto operator<=> (const array& x, const array& y) + -> decltype( x.elems[ 0 ] <=> y.elems[ 0 ] ) + { + for( std::size_t i = 0; i < N; ++i ) + { + auto r = x.elems[ i ] <=> y.elems[ i ]; + if( r != 0 ) return r; + } + + return std::strong_ordering::equal; + } + + template + constexpr auto operator<=> (const array& /*x*/, const array& /*y*/) + -> std::strong_ordering + { + return std::strong_ordering::equal; } - // Specific for boost::array: simply returns its elems data member. - template - typename detail::c_array::type& get_c_array(boost::array& arg) - { - return arg.elems; - } - - // Specific for boost::array: simply returns its elems data member. - template - typename detail::c_array::type const& get_c_array(const boost::array& arg) - { - return arg.elems; - } -#else -// Specific for boost::array: simply returns its elems data member. +# endif +#endif + + // undocumented and obsolete template + BOOST_DEPRECATED( "please use `elems` instead" ) T(&get_c_array(boost::array& arg))[N] { return arg.elems; @@ -386,49 +424,68 @@ namespace boost { // Const version. template + BOOST_DEPRECATED( "please use `elems` instead" ) const T(&get_c_array(const boost::array& arg))[N] { return arg.elems; } -#endif -#if 0 - // Overload for std::array, assuming that std::array will have - // explicit conversion functions as discussed at the WG21 meeting - // in Summit, March 2009. - template - T(&get_c_array(std::array& arg))[N] + template + BOOST_CXX14_CONSTEXPR T &get(boost::array &arr) BOOST_NOEXCEPT { - return static_cast(arg); + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" ); + return arr[Idx]; } - // Const version. - template - const T(&get_c_array(const std::array& arg))[N] + template + BOOST_CONSTEXPR const T &get(const boost::array &arr) BOOST_NOEXCEPT { - return static_cast(arg); + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" ); + return arr[Idx]; } -#endif - template std::size_t hash_range(It, It); + template + BOOST_CXX14_CONSTEXPR array to_array( T const (&a)[ N ] ) + { + array r = {}; + + for( std::size_t i = 0; i < N; ++i ) + { + r[ i ] = a[ i ]; + } + + return r; + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template - std::size_t hash_value(const array& arr) + BOOST_CXX14_CONSTEXPR array to_array( T (&&a)[ N ] ) { - return boost::hash_range(arr.begin(), arr.end()); + array r = {}; + + for( std::size_t i = 0; i < N; ++i ) + { + r[ i ] = std::move( a[ i ] ); + } + + return r; } - template - T &get(boost::array &arr) BOOST_NOEXCEPT { - BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" ); - return arr[Idx]; - } + template + BOOST_CXX14_CONSTEXPR array to_array( T const (&&a)[ N ] ) + { + array r = {}; - template - const T &get(const boost::array &arr) BOOST_NOEXCEPT { - BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" ); - return arr[Idx]; - } + for( std::size_t i = 0; i < N; ++i ) + { + r[ i ] = a[ i ]; + } + + return r; + } + +#endif } /* namespace boost */ @@ -436,12 +493,14 @@ namespace boost { // If we don't have std::array, I'm assuming that we don't have std::get namespace std { template + BOOST_DEPRECATED( "please use `boost::get` instead" ) T &get(boost::array &arr) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" ); return arr[Idx]; } template + BOOST_DEPRECATED( "please use `boost::get` instead" ) const T &get(const boost::array &arr) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" ); return arr[Idx]; @@ -453,4 +512,4 @@ namespace std { # pragma warning(pop) #endif -#endif /*BOOST_ARRAY_HPP*/ +#endif // #ifndef BOOST_ARRAY_HPP_INCLUDED diff --git a/index.html b/index.html index a9e3c343..c11ef89d 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - + Automatic redirection failed, please go to -../../doc/html/array.html  
-

© Copyright Beman Dawes, 2001

+doc/html/array.html  
+

© Copyright Beman Dawes, 2001

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)

- \ No newline at end of file + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dde5c33b..58f60aaf 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -7,6 +7,43 @@ import testing ; import-search /boost/config/checks ; import config : requires ; +project + : requirements + + /boost/array//boost_array + /boost/core//boost_core + + extra + + msvc:on + clang:on + gcc:on + + gcc-4.6:-Wno-missing-braces + gcc-4.7:-Wno-missing-braces + + gcc-4.6:-Wno-missing-field-initializers + gcc-4.7:-Wno-missing-field-initializers + gcc-4.8:-Wno-missing-field-initializers + gcc-4.9:-Wno-missing-field-initializers + + gcc-4.6:-Wno-type-limits + gcc-4.7:-Wno-type-limits + gcc-10:-Wno-type-limits + + clang:-Wno-unnamed-type-template-args + + clang-3.5:-Wno-missing-braces + clang-3.6:-Wno-missing-braces + clang-3.7:-Wno-missing-braces + clang-3.8:-Wno-missing-braces + clang-3.9:-Wno-missing-braces + clang-4:-Wno-missing-braces + clang-5:-Wno-missing-braces + ; + +# + run array0.cpp ; run array1.cpp ; run array2.cpp ; @@ -16,12 +53,59 @@ run array5.cpp ; run array6.cpp ; run array7.cpp ; -# run array_constexpr.cpp ; +compile array_constexpr.cpp ; -compile-fail array_getfail1.cpp ; -compile-fail array_getfail2.cpp ; +compile-fail array_getfail1.cpp + : off ; +compile-fail array_getfail2.cpp + : off ; run array_hash.cpp - : : : [ requires cxx11_noexcept ] ; + : : : /boost/container_hash//boost_container_hash [ requires cxx11_noexcept ] ; + +# + +run array_typedef_test.cpp ; +run array_elems_test.cpp ; +run array_init_test.cpp ; +run array_copy_test.cpp ; +run array_convert_test.cpp ; +run array_data_test.cpp ; +run array_iterator_test.cpp ; +run array_reverse_test.cpp ; +run array_size_test.cpp ; +run array_access_test.cpp ; +run array_c_array_test.cpp ; +run array_fill_test.cpp ; +run array_assign_test.cpp ; +run array_swap_test.cpp ; +run array_swap_test2.cpp ; +run array_eq_test.cpp ; +run array_lt_test.cpp ; +run array_thw_test.cpp ; +run array_get_test.cpp ; +run to_array_test.cpp ; + +# C++11 constexpr + +compile array_init_test_cx.cpp ; +compile array_copy_test_cx.cpp ; +compile array_data_test_cx.cpp ; +compile array_iterator_test_cx.cpp ; +compile array_size_test_cx.cpp ; +compile array_access_test_cx.cpp ; +compile array_get_test_cx.cpp ; + +# C++14 constexpr + +compile array_assign_test_cx.cpp ; +compile array_access_test_cx2.cpp ; +compile array_fill_test_cx.cpp ; +compile array_eq_test_cx.cpp ; +compile array_lt_test_cx.cpp ; +compile array_thw_test_cx.cpp ; +compile to_array_test_cx.cpp ; + +# run quick.cpp ; diff --git a/test/array0.cpp b/test/array0.cpp index af1d47bb..d1da316e 100644 --- a/test/array0.cpp +++ b/test/array0.cpp @@ -5,11 +5,11 @@ * http://www.boost.org/LICENSE_1_0.txt) */ -#include -#include #include - #include +#include +#include +#include namespace { @@ -44,7 +44,12 @@ void RunTests() BOOST_TEST ( const_test_case.begin() == const_test_case.end()); BOOST_TEST ( const_test_case.cbegin() == const_test_case.cend()); - BOOST_TEST ( test_case.begin() != const_test_case.begin() ); + // BOOST_TEST ( test_case.begin() != const_test_case.begin() ); + // + // TR1 specified that begin() must return a unique value for zero-sized + // arrays. However, this makes constexpr unimplementable, and all standard + // libraries have converged on using nullptr instead (see LWG issue 2157.) + if( test_case.data() == const_test_case.data() ) { // Value of data is unspecified in TR1, so no requirement this test pass or fail // However, it must compile! diff --git a/test/array5.cpp b/test/array5.cpp index 23156b9c..23352a7f 100644 --- a/test/array5.cpp +++ b/test/array5.cpp @@ -5,6 +5,8 @@ * http://www.boost.org/LICENSE_1_0.txt) */ +#define BOOST_ALLOW_DEPRECATED_SYMBOLS // assign + #include #include diff --git a/test/array6.cpp b/test/array6.cpp index d2cca910..65b8d477 100644 --- a/test/array6.cpp +++ b/test/array6.cpp @@ -5,12 +5,20 @@ * http://www.boost.org/LICENSE_1_0.txt) */ +#define BOOST_ALLOW_DEPRECATED_SYMBOLS // get_c_array + +#include +#include +#include #include #include -#include #include -#include +#if defined(BOOST_GCC) && BOOST_GCC / 10000 == 13 +// false -Warray-bounds positive when using -fsanitize=undefined +// restricted to GCC 13 because that's what is tested on Drone +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif namespace { template< class T > diff --git a/test/array7.cpp b/test/array7.cpp index 567b2e61..1e70108d 100644 --- a/test/array7.cpp +++ b/test/array7.cpp @@ -5,6 +5,8 @@ * http://www.boost.org/LICENSE_1_0.txt) */ +#define BOOST_ALLOW_DEPRECATED_SYMBOLS // std::get + #include #include #include diff --git a/test/array_access_test.cpp b/test/array_access_test.cpp new file mode 100644 index 00000000..b1ec6c8d --- /dev/null +++ b/test/array_access_test.cpp @@ -0,0 +1,117 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#define BOOST_ENABLE_ASSERT_HANDLER + +#include +#include +#include + +struct assertion_failure +{ +}; + +namespace boost +{ + +void assertion_failed( char const* /*expr*/, char const* /*function*/, char const* /*file*/, long /*line*/ ) +{ + throw assertion_failure(); +} + +void assertion_failed_msg( char const* /*expr*/, char const* /*msg*/, char const* /*function*/, char const* /*file*/, long /*line*/ ) +{ + throw assertion_failure(); +} + +} // namespace boost + +template void test() +{ + { + boost::array a = {{}}; + + T* p1 = a.data(); + + for( std::size_t i = 0; i < N; ++i ) + { + T* p2 = &a[ i ]; + T* p3 = &a.at( i ); + + BOOST_TEST_EQ( p2, p1 + i ); + BOOST_TEST_EQ( p3, p1 + i ); + } + + { + T* p2 = &a.front(); + T* p3 = &a.back(); + + BOOST_TEST_EQ( p2, p1 + 0 ); + BOOST_TEST_EQ( p3, p1 + N - 1 ); + } + + BOOST_TEST_THROWS( a.at( N ), std::out_of_range ); + BOOST_TEST_THROWS( a[ N ], assertion_failure ); + } + + { + boost::array const a = {{}}; + + T const* p1 = a.data(); + + for( std::size_t i = 0; i < N; ++i ) + { + T const* p2 = &a[ i ]; + T const* p3 = &a.at( i ); + + BOOST_TEST_EQ( p2, p1 + i ); + BOOST_TEST_EQ( p3, p1 + i ); + } + + { + T const* p2 = &a.front(); + T const* p3 = &a.back(); + + BOOST_TEST_EQ( p2, p1 + 0 ); + BOOST_TEST_EQ( p3, p1 + N - 1 ); + } + + BOOST_TEST_THROWS( a.at( N ), std::out_of_range ); + BOOST_TEST_THROWS( a[ N ], assertion_failure ); + } +} + +template void test2() +{ + { + boost::array a = {}; + + BOOST_TEST_THROWS( a.at( 0 ), std::out_of_range ); + BOOST_TEST_THROWS( a[ 0 ], std::out_of_range ); + BOOST_TEST_THROWS( a.front(), std::out_of_range ); + BOOST_TEST_THROWS( a.back(), std::out_of_range ); + } + + { + boost::array const a = {}; + + BOOST_TEST_THROWS( a.at( 0 ), std::out_of_range ); + BOOST_TEST_THROWS( a[ 0 ], std::out_of_range ); + BOOST_TEST_THROWS( a.front(), std::out_of_range ); + BOOST_TEST_THROWS( a.back(), std::out_of_range ); + } +} + +int main() +{ + test(); + test(); + + test(); + test(); + + test2(); + + return boost::report_errors(); +} diff --git a/test/array_access_test_cx.cpp b/test/array_access_test_cx.cpp new file mode 100644 index 00000000..507cd288 --- /dev/null +++ b/test/array_access_test_cx.cpp @@ -0,0 +1,50 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test() +{ + constexpr boost::array a = {{}}; + + STATIC_ASSERT( &a[ 0 ] == a.data() + 0 ); + STATIC_ASSERT( &a[ 1 ] == a.data() + 1 ); + STATIC_ASSERT( &a[ 2 ] == a.data() + 2 ); + STATIC_ASSERT( &a[ 3 ] == a.data() + 3 ); + + STATIC_ASSERT( &a.at( 0 ) == a.data() + 0 ); + STATIC_ASSERT( &a.at( 1 ) == a.data() + 1 ); + STATIC_ASSERT( &a.at( 2 ) == a.data() + 2 ); + STATIC_ASSERT( &a.at( 3 ) == a.data() + 3 ); + + STATIC_ASSERT( &a.front() == a.data() ); + STATIC_ASSERT( &a.back() == a.data() + 3 ); +} + +int main() +{ + test(); +} + +#endif diff --git a/test/array_access_test_cx2.cpp b/test/array_access_test_cx2.cpp new file mode 100644 index 00000000..18dbbf4d --- /dev/null +++ b/test/array_access_test_cx2.cpp @@ -0,0 +1,45 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template constexpr boost::array modified( boost::array a1 ) +{ + a1.front() = 1; + a1[ 1 ] = 2; + a1.at( 2 ) = 3; + a1.back() = 4; + + return a1; +} + +template void test1() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = modified( a1 ); + + STATIC_ASSERT( a2[0] == 1 ); + STATIC_ASSERT( a2[1] == 2 ); + STATIC_ASSERT( a2[2] == 3 ); + STATIC_ASSERT( a2[3] == 4 ); +} + +int main() +{ + test1(); +} + +#endif diff --git a/test/array_assign_test.cpp b/test/array_assign_test.cpp new file mode 100644 index 00000000..44fa9473 --- /dev/null +++ b/test/array_assign_test.cpp @@ -0,0 +1,65 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#define BOOST_ALLOW_DEPRECATED_SYMBOLS + +// assign is a deprecated nonstandard equivalent of fill + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + boost::array a = {}; + + a.assign( 1 ); + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a[i], 1 ); + } +} + +template void test2() +{ + boost::array a = {{ 1, 2, 3, 4 }}; + + a.assign( 5 ); + + for( std::size_t i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a[i], 5 ); + } +} + +template void test3() +{ + boost::array a = {{ 1, 2, 3, 4 }}; + + // aliasing + a.assign( a[ 1 ] ); + + for( std::size_t i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a[i], 2 ); + } +} + +int main() +{ + test(); + test(); + test(); + + test2(); + + test3(); + + return boost::report_errors(); +} diff --git a/test/array_assign_test_cx.cpp b/test/array_assign_test_cx.cpp new file mode 100644 index 00000000..d767636c --- /dev/null +++ b/test/array_assign_test_cx.cpp @@ -0,0 +1,54 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template constexpr boost::array assigned( boost::array const& a1 ) +{ + boost::array a2 = {}; + + a2 = a1; + + return a2; +} + +template void test1() +{ + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = assigned( a1 ); + + STATIC_ASSERT( a1[0] == a2[0] ); + STATIC_ASSERT( a1[1] == a2[1] ); + STATIC_ASSERT( a1[2] == a2[2] ); + STATIC_ASSERT( a1[3] == a2[3] ); +} + +template void test2() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = assigned( a1 ); + + (void)a1; + (void)a2; +} + +int main() +{ + test1(); + test2(); +} + +#endif diff --git a/test/array_c_array_test.cpp b/test/array_c_array_test.cpp new file mode 100644 index 00000000..89751d14 --- /dev/null +++ b/test/array_c_array_test.cpp @@ -0,0 +1,71 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#define BOOST_ALLOW_DEPRECATED_SYMBOLS + +#include +#include +#include +#include +#include + +// c_array and get_c_array are deprecated nonstandard extensions + +template void test() +{ + boost::array a = {}; + + T* p1 = a.c_array(); + T* p2 = a.data(); + + BOOST_TEST_EQ( p1, p2 ); +} + +template void test2() +{ + { + boost::array a = {{}}; + + T (&e1)[ N ] = boost::get_c_array( a ); + T (&e2)[ N ] = a.elems; + + BOOST_TEST_EQ( static_cast( e1 ), static_cast( e2 ) ); + } + { + boost::array const a = {{}}; + + T const (&e1)[ N ] = boost::get_c_array( a ); + T const (&e2)[ N ] = a.elems; + + BOOST_TEST_EQ( static_cast( e1 ), static_cast( e2 ) ); + } +} + +int main() +{ + test(); + test(); + test(); + + test(); + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1910) || BOOST_WORKAROUND(BOOST_GCC, < 50000) + + // = {} doesn't work for const T + +#else + + test(); + test(); + +#endif + + test2(); + test2(); + + test2(); + test2(); + + return boost::report_errors(); +} diff --git a/test/array_constexpr.cpp b/test/array_constexpr.cpp index 48995c9f..a6c0dc6e 100644 --- a/test/array_constexpr.cpp +++ b/test/array_constexpr.cpp @@ -5,27 +5,15 @@ * http://www.boost.org/LICENSE_1_0.txt) */ -#include -#include #include -#include -#ifndef BOOST_NO_CXX11_HDR_ARRAY -#include -#endif +#include #ifndef BOOST_NO_CXX11_CONSTEXPR -constexpr boost::array arr {{ 0,1,2,3,4,5,6,7,8,9 }}; -constexpr std::array arr_std {{ 0,1,2,3,4,5,6,7,8,9 }}; - -template -void sink ( T t ) {} -template -void sink ( boost::array &arr ) {} +constexpr boost::array arr {{ 0,1,2,3,4,5,6,7,8,9 }}; int main() { -// constexpr int two = arr_std.at (2); constexpr int three = arr.at (3); int whatever [ arr.at(4) ]; (void)three; @@ -33,7 +21,9 @@ int main() } #else // no constexpr means no constexpr tests! + int main() { } + #endif diff --git a/test/array_convert_test.cpp b/test/array_convert_test.cpp new file mode 100644 index 00000000..7060ec8c --- /dev/null +++ b/test/array_convert_test.cpp @@ -0,0 +1,38 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test2() +{ + boost::array a1 = {}; + + boost::array a2; + a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +template void test4() +{ + boost::array a1 = { 1, 2, 3, 4 }; + + boost::array a2; + a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +int main() +{ + test2(); + test2(); + test2(); + + test4(); + + return boost::report_errors(); +} diff --git a/test/array_copy_test.cpp b/test/array_copy_test.cpp new file mode 100644 index 00000000..5701f5b1 --- /dev/null +++ b/test/array_copy_test.cpp @@ -0,0 +1,65 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test1() +{ + boost::array a1 = {{}}; + boost::array a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +template void test2() +{ + boost::array a1 = {}; + + boost::array a2; + a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +template void test3() +{ + boost::array a1 = {{ 1, 2, 3, 4 }}; + boost::array a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +template void test4() +{ + boost::array a1 = { 1, 2, 3, 4 }; + + boost::array a2; + a2 = a1; + + BOOST_TEST_ALL_EQ( a1.begin(), a1.end(), a2.begin(), a2.end() ); +} + +int main() +{ + test1(); + test1(); + test1(); + + test1(); + test1(); + test1(); + + test2(); + test2(); + test2(); + + test3(); + test3(); + + test4(); + + return boost::report_errors(); +} diff --git a/test/array_copy_test_cx.cpp b/test/array_copy_test_cx.cpp new file mode 100644 index 00000000..a22c3774 --- /dev/null +++ b/test/array_copy_test_cx.cpp @@ -0,0 +1,58 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = a1; + + STATIC_ASSERT( a1[0] == a2[0] ); + STATIC_ASSERT( a1[1] == a2[1] ); +} + +template void test2() +{ + constexpr boost::array a1 = {{ 1, 2, 3 }}; + constexpr boost::array a2 = a1; + + STATIC_ASSERT( a1[0] == a2[0] ); + STATIC_ASSERT( a1[1] == a2[1] ); + STATIC_ASSERT( a1[2] == a2[2] ); +} + +template void test3() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = a1; + + (void)a1; + (void)a2; +} + +int main() +{ + test1(); + test2(); + test3(); +} + +#endif diff --git a/test/array_data_test.cpp b/test/array_data_test.cpp new file mode 100644 index 00000000..432139aa --- /dev/null +++ b/test/array_data_test.cpp @@ -0,0 +1,41 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test() +{ + { + boost::array a = {{}}; + + T* p1 = a.data(); + T* p2 = a.elems; + + BOOST_TEST_EQ( p1, p2 ); + } + + { + boost::array const a = {{}}; + + T const* p1 = a.data(); + T const* p2 = a.elems; + + BOOST_TEST_EQ( p1, p2 ); + } +} + +int main() +{ + // test(); + test(); + test(); + + // test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/array_data_test_cx.cpp b/test/array_data_test_cx.cpp new file mode 100644 index 00000000..f567b39a --- /dev/null +++ b/test/array_data_test_cx.cpp @@ -0,0 +1,47 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a = {}; + STATIC_ASSERT( a.data() == a.elems ); +} + +template void test2() +{ + constexpr boost::array a = {}; + STATIC_ASSERT( a.data() == 0 ); +} + +int main() +{ + test1(); + test1(); + + test2(); +} + +#endif diff --git a/test/array_elems_test.cpp b/test/array_elems_test.cpp new file mode 100644 index 00000000..0773882c --- /dev/null +++ b/test/array_elems_test.cpp @@ -0,0 +1,27 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test() +{ + boost::array a = {{}}; + + T (&e)[ N ] = a.elems; + + BOOST_TEST_EQ( static_cast( e ), static_cast( &a ) ); +} + +int main() +{ + test(); + test(); + + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/array_eq_test.cpp b/test/array_eq_test.cpp new file mode 100644 index 00000000..e85ad317 --- /dev/null +++ b/test/array_eq_test.cpp @@ -0,0 +1,87 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + { + boost::array const a1 = {}; + boost::array const a2 = {}; + + BOOST_TEST( a1 == a2 ); + BOOST_TEST_NOT( a1 != a2 ); + } + + for( std::size_t i = 0; i < N; ++i ) + { + boost::array const a1 = {}; + + boost::array a2 = a1; + a2[ i ] = 1; + + BOOST_TEST( a1 != a2 ); + BOOST_TEST_NOT( a1 == a2 ); + + boost::array const a3 = a2; + + BOOST_TEST( a1 != a3 ); + BOOST_TEST_NOT( a1 == a3 ); + } + + { + boost::array a1 = {}; + boost::array a2 = {}; + + a1.fill( 1 ); + a2.fill( 1 ); + + BOOST_TEST( a1 == a2 ); + BOOST_TEST_NOT( a1 != a2 ); + } +} + +template void test2() +{ + { + boost::array const a1 = {{ 1, 2, 3, 4 }}; + boost::array const a2 = {{ 1, 2, 3, 4 }}; + + BOOST_TEST( a1 == a2 ); + BOOST_TEST_NOT( a1 != a2 ); + } + + for( std::size_t i = 0; i < 4; ++i ) + { + boost::array const a1 = {{ 1, 2, 3, 4 }}; + + boost::array a2 = a1; + a2[ i ] = 0; + + BOOST_TEST( a1 != a2 ); + BOOST_TEST_NOT( a1 == a2 ); + + boost::array const a3 = a2; + + BOOST_TEST( a1 != a3 ); + BOOST_TEST_NOT( a1 == a3 ); + } +} + +int main() +{ + test(); + test(); + test(); + + test2(); + + return boost::report_errors(); +} diff --git a/test/array_eq_test_cx.cpp b/test/array_eq_test_cx.cpp new file mode 100644 index 00000000..6fe7ea19 --- /dev/null +++ b/test/array_eq_test_cx.cpp @@ -0,0 +1,55 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = {}; + + STATIC_ASSERT( a1 == a2 ); + STATIC_ASSERT( !( a1 != a2 ) ); +} + +template void test2() +{ + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 4 }}; + + STATIC_ASSERT( a1 == a2 ); + STATIC_ASSERT( !( a1 != a2 ) ); + } + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 5 }}; + + STATIC_ASSERT( !( a1 == a2 ) ); + STATIC_ASSERT( a1 != a2 ); + } +} + +int main() +{ + test1(); + test1(); + test1(); + + test2(); +} + +#endif diff --git a/test/array_fill_test.cpp b/test/array_fill_test.cpp new file mode 100644 index 00000000..f8fc92dd --- /dev/null +++ b/test/array_fill_test.cpp @@ -0,0 +1,61 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + boost::array a = {}; + + a.fill( 1 ); + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a[i], 1 ); + } +} + +template void test2() +{ + boost::array a = {{ 1, 2, 3, 4 }}; + + a.fill( 5 ); + + for( std::size_t i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a[i], 5 ); + } +} + +template void test3() +{ + boost::array a = {{ 1, 2, 3, 4 }}; + + // aliasing + a.fill( a[ 1 ] ); + + for( std::size_t i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a[i], 2 ); + } +} + +int main() +{ + test(); + test(); + test(); + + test2(); + + test3(); + + return boost::report_errors(); +} diff --git a/test/array_fill_test_cx.cpp b/test/array_fill_test_cx.cpp new file mode 100644 index 00000000..9fd4a8a7 --- /dev/null +++ b/test/array_fill_test_cx.cpp @@ -0,0 +1,51 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template constexpr boost::array filled( T const& v ) +{ + boost::array r = {}; + + r.fill( v ); + + return r; +} + +template void test1() +{ + constexpr boost::array a1 = filled( 7 ); + + STATIC_ASSERT( a1[0] == 7 ); + STATIC_ASSERT( a1[1] == 7 ); + STATIC_ASSERT( a1[2] == 7 ); + STATIC_ASSERT( a1[3] == 7 ); +} + +template void test2() +{ + constexpr boost::array a1 = filled( 7 ); + + (void)a1; +} + +int main() +{ + test1(); + test2(); +} + +#endif diff --git a/test/array_get_test.cpp b/test/array_get_test.cpp new file mode 100644 index 00000000..bc45669b --- /dev/null +++ b/test/array_get_test.cpp @@ -0,0 +1,40 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test() +{ + { + boost::array const a = {{ 1, 2, 3, 4 }}; + + BOOST_TEST_EQ( boost::get<0>( a ), 1 ); + BOOST_TEST_EQ( boost::get<1>( a ), 2 ); + BOOST_TEST_EQ( boost::get<2>( a ), 3 ); + BOOST_TEST_EQ( boost::get<3>( a ), 4 ); + } + + { + boost::array a = {{ 1, 2, 3, 4 }}; + + boost::get<0>( a ) += 1; + boost::get<1>( a ) += 2; + boost::get<2>( a ) += 3; + boost::get<3>( a ) += 4; + + BOOST_TEST_EQ( boost::get<0>( a ), 2 ); + BOOST_TEST_EQ( boost::get<1>( a ), 4 ); + BOOST_TEST_EQ( boost::get<2>( a ), 6 ); + BOOST_TEST_EQ( boost::get<3>( a ), 8 ); + } +} + +int main() +{ + test(); + + return boost::report_errors(); +} diff --git a/test/array_get_test_cx.cpp b/test/array_get_test_cx.cpp new file mode 100644 index 00000000..693afa17 --- /dev/null +++ b/test/array_get_test_cx.cpp @@ -0,0 +1,42 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test() +{ + constexpr boost::array a = {{ 1, 2, 3, 4 }}; + + STATIC_ASSERT( boost::get<0>( a ) == 1 ); + STATIC_ASSERT( boost::get<1>( a ) == 2 ); + STATIC_ASSERT( boost::get<2>( a ) == 3 ); + STATIC_ASSERT( boost::get<3>( a ) == 4 ); +} + +int main() +{ + test(); +} + +#endif diff --git a/test/array_init_test.cpp b/test/array_init_test.cpp new file mode 100644 index 00000000..33889457 --- /dev/null +++ b/test/array_init_test.cpp @@ -0,0 +1,85 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test1() +{ + boost::array a = {{}}; + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a[i], T() ); + } +} + +template void test2() +{ + boost::array a = {}; + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a[i], T() ); + } +} + +template void test3() +{ + boost::array a = {{ 1, 2, 3, 4 }}; + T b[ 4 ] = { 1, 2, 3, 4 }; + + BOOST_TEST_ALL_EQ( a.begin(), a.end(), b + 0, b + 4 ); +} + +template void test4() +{ + boost::array a = { 1, 2, 3, 4 }; + T b[ 4 ] = { 1, 2, 3, 4 }; + + BOOST_TEST_ALL_EQ( a.begin(), a.end(), b + 0, b + 4 ); +} + +int main() +{ + test1(); + test1(); + test1(); + + test1(); + test1(); + test1(); + + test2(); + test2(); + test2(); + + test2(); + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1910) || BOOST_WORKAROUND(BOOST_GCC, < 50000) + + // = {} doesn't work for const T + +#else + + test2(); + test2(); + +#endif + + test3(); + test3(); + + test4(); + test4(); + + return boost::report_errors(); +} diff --git a/test/array_init_test_cx.cpp b/test/array_init_test_cx.cpp new file mode 100644 index 00000000..1a8cfd23 --- /dev/null +++ b/test/array_init_test_cx.cpp @@ -0,0 +1,79 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a = {{}}; + + STATIC_ASSERT( a[0] == 0 ); +} + +template void test2() +{ + constexpr boost::array a = {}; + + STATIC_ASSERT( a[0] == 0 ); + STATIC_ASSERT( a[1] == 0 ); +} + +template void test3() +{ + constexpr boost::array a = {{ 1, 2, 3 }}; + + STATIC_ASSERT( a[0] == 1 ); + STATIC_ASSERT( a[1] == 2 ); + STATIC_ASSERT( a[2] == 3 ); +} + +template void test4() +{ + constexpr boost::array a = { 1, 2, 3, 4 }; + + STATIC_ASSERT( a[0] == 1 ); + STATIC_ASSERT( a[1] == 2 ); + STATIC_ASSERT( a[2] == 3 ); + STATIC_ASSERT( a[3] == 4 ); +} + +template void test5() +{ + constexpr boost::array a = {{}}; + (void)a; +} + +template void test6() +{ + constexpr boost::array a = {}; + (void)a; +} + +int main() +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); +} + +#endif diff --git a/test/array_iterator_test.cpp b/test/array_iterator_test.cpp new file mode 100644 index 00000000..a88dd281 --- /dev/null +++ b/test/array_iterator_test.cpp @@ -0,0 +1,108 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +template void test() +{ + { + boost::array a = {{}}; + + T* p1 = a.data(); + + { + T* p2 = a.begin(); + T* p3 = a.end(); + + BOOST_TEST_EQ( p2, p1 ); + BOOST_TEST_EQ( p3, p1 + N ); + } + + { + T const* p2 = a.cbegin(); + T const* p3 = a.cend(); + + BOOST_TEST_EQ( p2, p1 ); + BOOST_TEST_EQ( p3, p1 + N ); + } + } + + { + boost::array const a = {{}}; + + T const* p1 = a.data(); + + { + T const* p2 = a.begin(); + T const* p3 = a.end(); + + BOOST_TEST_EQ( p2, p1 ); + BOOST_TEST_EQ( p3, p1 + N ); + } + + { + T const* p2 = a.cbegin(); + T const* p3 = a.cend(); + + BOOST_TEST_EQ( p2, p1 ); + BOOST_TEST_EQ( p3, p1 + N ); + } + } +} + +template void test2() +{ + { + boost::array a = {}; + + { + T* p2 = a.begin(); + T* p3 = a.end(); + + BOOST_TEST_EQ( p2, p3 ); + } + + { + T const* p2 = a.cbegin(); + T const* p3 = a.cend(); + + BOOST_TEST_EQ( p2, p3 ); + } + } + + { + boost::array const a = {}; + + { + T const* p2 = a.begin(); + T const* p3 = a.end(); + + BOOST_TEST_EQ( p2, p3 ); + } + + { + T const* p2 = a.cbegin(); + T const* p3 = a.cend(); + + BOOST_TEST_EQ( p2, p3 ); + } + } +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + test2(); + + return boost::report_errors(); +} diff --git a/test/array_iterator_test_cx.cpp b/test/array_iterator_test_cx.cpp new file mode 100644 index 00000000..92598987 --- /dev/null +++ b/test/array_iterator_test_cx.cpp @@ -0,0 +1,55 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910") + +#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a = {}; + + STATIC_ASSERT( a.begin() == a.data() ); + STATIC_ASSERT( a.end() == a.data() + N ); + + STATIC_ASSERT( a.cbegin() == a.data() ); + STATIC_ASSERT( a.cend() == a.data() + N ); +} + +template void test2() +{ + constexpr boost::array a = {}; + + STATIC_ASSERT( a.begin() == a.end() ); + STATIC_ASSERT( a.cbegin() == a.cend() ); +} + +int main() +{ + test1(); + test1(); + test1(); + + test2(); +} + +#endif diff --git a/test/array_lt_test.cpp b/test/array_lt_test.cpp new file mode 100644 index 00000000..bed29f6d --- /dev/null +++ b/test/array_lt_test.cpp @@ -0,0 +1,89 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + { + boost::array const a1 = {}; + boost::array const a2 = {}; + + BOOST_TEST_NOT( a1 < a2 ); + BOOST_TEST_NOT( a1 > a2 ); + BOOST_TEST( a1 <= a2 ); + BOOST_TEST( a1 >= a2 ); + } + + { + boost::array a1; + boost::array a2; + + a1.fill( 1 ); + a2.fill( 1 ); + + BOOST_TEST_NOT( a1 < a2 ); + BOOST_TEST_NOT( a1 > a2 ); + BOOST_TEST( a1 <= a2 ); + BOOST_TEST( a1 >= a2 ); + } + + for( std::size_t i = 0; i < N; ++i ) + { + boost::array a1; + boost::array a2; + + a1.fill( 1 ); + a2.fill( 1 ); + + a1[ i ] = 0; + + BOOST_TEST( a1 < a2 ); + BOOST_TEST( a1 <= a2 ); + BOOST_TEST_NOT( a1 > a2 ); + BOOST_TEST_NOT( a1 >= a2 ); + + { + boost::array const a3 = a1; + boost::array const a4 = a2; + + BOOST_TEST( a3 < a4 ); + BOOST_TEST( a3 <= a4 ); + BOOST_TEST_NOT( a3 > a4 ); + BOOST_TEST_NOT( a3 >= a4 ); + } + + a1[ i ] = 2; + + BOOST_TEST( a1 > a2 ); + BOOST_TEST( a1 >= a2 ); + BOOST_TEST_NOT( a1 < a2 ); + BOOST_TEST_NOT( a1 <= a2 ); + + { + boost::array const a3 = a1; + boost::array const a4 = a2; + + BOOST_TEST( a3 > a4 ); + BOOST_TEST( a3 >= a4 ); + BOOST_TEST_NOT( a3 < a4 ); + BOOST_TEST_NOT( a3 <= a4 ); + } + } +} + +int main() +{ + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/array_lt_test_cx.cpp b/test/array_lt_test_cx.cpp new file mode 100644 index 00000000..fff2e950 --- /dev/null +++ b/test/array_lt_test_cx.cpp @@ -0,0 +1,74 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a1 = {}; + constexpr boost::array a2 = {}; + + STATIC_ASSERT( !( a1 < a2 ) ); + STATIC_ASSERT( !( a1 > a2 ) ); + + STATIC_ASSERT( a1 <= a2 ); + STATIC_ASSERT( a1 >= a2 ); +} + +template void test2() +{ + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 4 }}; + + STATIC_ASSERT( !( a1 < a2 ) ); + STATIC_ASSERT( !( a1 > a2 ) ); + + STATIC_ASSERT( a1 <= a2 ); + STATIC_ASSERT( a1 >= a2 ); + } + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 5 }}; + + STATIC_ASSERT( a1 < a2 ); + STATIC_ASSERT( !( a1 > a2 ) ); + + STATIC_ASSERT( a1 <= a2 ); + STATIC_ASSERT( !( a1 >= a2 ) ); + } + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 2 }}; + + STATIC_ASSERT( !( a1 < a2 ) ); + STATIC_ASSERT( a1 > a2 ); + + STATIC_ASSERT( !( a1 <= a2 ) ); + STATIC_ASSERT( a1 >= a2 ); + } +} + +int main() +{ + test1(); + test1(); + test1(); + + test2(); +} + +#endif diff --git a/test/array_reverse_test.cpp b/test/array_reverse_test.cpp new file mode 100644 index 00000000..0f3fcea2 --- /dev/null +++ b/test/array_reverse_test.cpp @@ -0,0 +1,88 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +template void test() +{ + { + boost::array a = {{}}; + + { + std::reverse_iterator r1( a.rbegin() ); + std::reverse_iterator r2( a.end() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.rend() ); + std::reverse_iterator r2( a.begin() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.crbegin() ); + std::reverse_iterator r2( a.cend() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.crend() ); + std::reverse_iterator r2( a.cbegin() ); + + BOOST_TEST( r1 == r2 ); + } + } + + { + boost::array const a = {{}}; + + { + std::reverse_iterator r1( a.rbegin() ); + std::reverse_iterator r2( a.end() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.rend() ); + std::reverse_iterator r2( a.begin() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.crbegin() ); + std::reverse_iterator r2( a.cend() ); + + BOOST_TEST( r1 == r2 ); + } + + { + std::reverse_iterator r1( a.crend() ); + std::reverse_iterator r2( a.cbegin() ); + + BOOST_TEST( r1 == r2 ); + } + } +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/array_size_test.cpp b/test/array_size_test.cpp new file mode 100644 index 00000000..a4c493dd --- /dev/null +++ b/test/array_size_test.cpp @@ -0,0 +1,77 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +template void test1() +{ + { + boost::array a = {{}}; + + BOOST_TEST_EQ( a.size(), N ); + BOOST_TEST_EQ( a.empty(), N == 0 ); + BOOST_TEST_EQ( a.max_size(), N ); + + (void)a; // msvc-12.0 + } + + { + boost::array const a = {{}}; + + BOOST_TEST_EQ( a.size(), N ); + BOOST_TEST_EQ( a.empty(), N == 0 ); + BOOST_TEST_EQ( a.max_size(), N ); + + (void)a; // msvc-12.0 + } +} + +template void test2() +{ + typedef boost::array A; + + BOOST_TEST_EQ( A().size(), N ); + BOOST_TEST_EQ( A().empty(), N == 0 ); + BOOST_TEST_EQ( A().max_size(), N ); +} + +// the functions are static, which deviates from the standard +template void test3() +{ + typedef boost::array A; + + BOOST_TEST_EQ( A::size(), N ); + BOOST_TEST_EQ( A::empty(), N == 0 ); + BOOST_TEST_EQ( A::max_size(), N ); + + BOOST_TEST_EQ( A::static_size, N ); +} + +int main() +{ + test1(); + test1(); + test1(); + + test1(); + test1(); + test1(); + + test2(); + test2(); + test2(); + + test3(); + test3(); + test3(); + + test3(); + test3(); + test3(); + + return boost::report_errors(); +} diff --git a/test/array_size_test_cx.cpp b/test/array_size_test_cx.cpp new file mode 100644 index 00000000..bc3d6a5c --- /dev/null +++ b/test/array_size_test_cx.cpp @@ -0,0 +1,64 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr boost::array a = {}; + + STATIC_ASSERT( a.size() == N ); + STATIC_ASSERT( a.empty() == (N == 0) ); + STATIC_ASSERT( a.max_size() == N ); +} + +template void test2() +{ + typedef boost::array A; + + STATIC_ASSERT( A().size() == N ); + STATIC_ASSERT( A().empty() == (N == 0) ); + STATIC_ASSERT( A().max_size() == N ); +} + +// the functions are static, which deviates from the standard +template void test3() +{ + typedef boost::array A; + + STATIC_ASSERT( A::size() == N ); + STATIC_ASSERT( A::empty() == (N == 0) ); + STATIC_ASSERT( A::max_size() == N ); + + STATIC_ASSERT( A::static_size == N ); +} + +int main() +{ + test1(); + test1(); + test1(); + + test2(); + test2(); + test2(); + + test3(); + test3(); + test3(); +} + +#endif diff --git a/test/array_swap_test.cpp b/test/array_swap_test.cpp new file mode 100644 index 00000000..db4733a2 --- /dev/null +++ b/test/array_swap_test.cpp @@ -0,0 +1,53 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + boost::array a1 = {}; + boost::array a2 = {}; + + a1.fill( 1 ); + a2.fill( 2 ); + + a1.swap( a2 ); + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a1[i], 2 ); + BOOST_TEST_EQ( a2[i], 1 ); + } +} + +template void test2() +{ + boost::array a1 = {{ 1, 2, 3, 4 }}; + boost::array a2 = {{ 5, 6, 7, 8 }}; + + a1.swap( a2 ); + + for( int i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a1[i], i+5 ); + BOOST_TEST_EQ( a2[i], i+1 ); + } +} + +int main() +{ + test(); + test(); + test(); + + test2(); + + return boost::report_errors(); +} diff --git a/test/array_swap_test2.cpp b/test/array_swap_test2.cpp new file mode 100644 index 00000000..5007f561 --- /dev/null +++ b/test/array_swap_test2.cpp @@ -0,0 +1,53 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable: 4702) // unreachable code +#endif + +template void test() +{ + boost::array a1 = {}; + boost::array a2 = {}; + + a1.fill( 1 ); + a2.fill( 2 ); + + swap( a1, a2 ); + + for( std::size_t i = 0; i < N; ++i ) + { + BOOST_TEST_EQ( a1[i], 2 ); + BOOST_TEST_EQ( a2[i], 1 ); + } +} + +template void test2() +{ + boost::array a1 = {{ 1, 2, 3, 4 }}; + boost::array a2 = {{ 5, 6, 7, 8 }}; + + swap( a1, a2 ); + + for( int i = 0; i < 4; ++i ) + { + BOOST_TEST_EQ( a1[i], i+5 ); + BOOST_TEST_EQ( a2[i], i+1 ); + } +} + +int main() +{ + test(); + test(); + test(); + + test2(); + + return boost::report_errors(); +} diff --git a/test/array_thw_test.cpp b/test/array_thw_test.cpp new file mode 100644 index 00000000..357c1eae --- /dev/null +++ b/test/array_thw_test.cpp @@ -0,0 +1,102 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(__has_include) +# if __has_include() +# define HAS_COMPARE +# endif +#endif + +#if !defined(__cpp_impl_three_way_comparison) + +BOOST_PRAGMA_MESSAGE( "Test skipped because __cpp_impl_three_way_comparison is not defined" ) +int main() {} + +#elif !( __cpp_impl_three_way_comparison >= 201907L ) + +BOOST_PRAGMA_MESSAGE( "Test skipped because __cpp_impl_three_way_comparison is defined to " BOOST_STRINGIZE(__cpp_impl_three_way_comparison) ) +int main() {} + +#elif !defined(HAS_COMPARE) + +BOOST_PRAGMA_MESSAGE( "Test skipped because is not available" ) +int main() {} + +#else + +template void test() +{ + constexpr auto eq = 0 <=> 0; + constexpr auto lt = 0 <=> 1; + constexpr auto gt = 1 <=> 0; + + { + boost::array const a1 = {}; + boost::array const a2 = {}; + + BOOST_TEST( ( a1 <=> a2 ) == eq ); + } + + { + boost::array a1; + boost::array a2; + + a1.fill( 1 ); + a2.fill( 1 ); + + BOOST_TEST( ( a1 <=> a2 ) == eq ); + } + + for( std::size_t i = 0; i < N; ++i ) + { + boost::array a1; + boost::array a2; + + a1.fill( 1 ); + a2.fill( 1 ); + + a1[ i ] = 0; + + BOOST_TEST( ( a1 <=> a2 ) == lt ); + + { + boost::array const a3 = a1; + boost::array const a4 = a2; + + BOOST_TEST( ( a3 <=> a4 ) == lt ); + } + + a1[ i ] = 2; + + BOOST_TEST( ( a1 <=> a2 ) == gt ); + + { + boost::array const a3 = a1; + boost::array const a4 = a2; + + BOOST_TEST( ( a3 <=> a4 ) == gt ); + } + } +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} + +#endif diff --git a/test/array_thw_test_cx.cpp b/test/array_thw_test_cx.cpp new file mode 100644 index 00000000..f9deae94 --- /dev/null +++ b/test/array_thw_test_cx.cpp @@ -0,0 +1,81 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(__has_include) +# if __has_include() +# define HAS_COMPARE +# endif +#endif + +#if !defined(__cpp_impl_three_way_comparison) + +BOOST_PRAGMA_MESSAGE( "Test skipped because __cpp_impl_three_way_comparison is not defined" ) +int main() {} + +#elif !( __cpp_impl_three_way_comparison >= 201907L ) + +BOOST_PRAGMA_MESSAGE( "Test skipped because __cpp_impl_three_way_comparison is defined to " BOOST_STRINGIZE(__cpp_impl_three_way_comparison) ) +int main() {} + +#elif !defined(HAS_COMPARE) + +BOOST_PRAGMA_MESSAGE( "Test skipped because is not available" ) +int main() {} + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template void test1() +{ + constexpr auto eq = 0 <=> 0; + + constexpr boost::array a1 = {}; + constexpr boost::array a2 = {}; + + STATIC_ASSERT( ( a1 <=> a2 ) == eq ); +} + +template void test2() +{ + constexpr auto eq = 0 <=> 0; + constexpr auto lt = 0 <=> 1; + constexpr auto gt = 1 <=> 0; + + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 4 }}; + + STATIC_ASSERT( ( a1 <=> a2 ) == eq ); + } + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 5 }}; + + STATIC_ASSERT( ( a1 <=> a2 ) == lt ); + } + { + constexpr boost::array a1 = {{ 1, 2, 3, 4 }}; + constexpr boost::array a2 = {{ 1, 2, 3, 2 }}; + + STATIC_ASSERT( ( a1 <=> a2 ) == gt ); + } +} + +int main() +{ + test1(); + test1(); + test1(); + + test2(); +} + +#endif diff --git a/test/array_typedef_test.cpp b/test/array_typedef_test.cpp new file mode 100644 index 00000000..82010377 --- /dev/null +++ b/test/array_typedef_test.cpp @@ -0,0 +1,43 @@ +// Copyright 2025 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 void test() +{ + typedef boost::array A; + + BOOST_TEST_TRAIT_SAME(typename A::value_type, T); + + BOOST_TEST_TRAIT_SAME(typename A::iterator, T*); + BOOST_TEST_TRAIT_SAME(typename A::const_iterator, T const*); + + BOOST_TEST_TRAIT_SAME(typename A::reverse_iterator, std::reverse_iterator); + BOOST_TEST_TRAIT_SAME(typename A::const_reverse_iterator, std::reverse_iterator); + + BOOST_TEST_TRAIT_SAME(typename A::reference, T&); + BOOST_TEST_TRAIT_SAME(typename A::const_reference, T const&); + + BOOST_TEST_TRAIT_SAME(typename A::size_type, std::size_t); + BOOST_TEST_TRAIT_SAME(typename A::difference_type, std::ptrdiff_t); + + BOOST_TEST_EQ(A::static_size, N); +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt index ea0eae9d..8562d75c 100644 --- a/test/cmake_subdir_test/CMakeLists.txt +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -11,7 +11,6 @@ add_subdirectory(../.. boostorg/array) add_subdirectory(../../../assert boostorg/assert) add_subdirectory(../../../config boostorg/config) add_subdirectory(../../../core boostorg/core) -add_subdirectory(../../../static_assert boostorg/static_assert) add_subdirectory(../../../throw_exception boostorg/throw_exception) add_executable(quick ../quick.cpp) diff --git a/test/quick.cpp b/test/quick.cpp index c59a2c64..ecb5ec0b 100644 --- a/test/quick.cpp +++ b/test/quick.cpp @@ -1,6 +1,6 @@ // Copyright 2023 Peter Dimov. // Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt) +// https://www.boost.org/LICENSE_1_0.txt #include diff --git a/test/to_array_test.cpp b/test/to_array_test.cpp new file mode 100644 index 00000000..0fd6dff9 --- /dev/null +++ b/test/to_array_test.cpp @@ -0,0 +1,109 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include + +boost::array f1() +{ + boost::array r = {{ 1, 2, 3 }}; + return r; +} + +boost::array const f2() +{ + boost::array r = {{ 1, 2, 3 }}; + return r; +} + +int main() +{ + { + int a[] = { 1, 2, 3 }; + + boost::array b = boost::to_array( a ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } + + { + int const a[] = { 1, 2, 3 }; + + boost::array b = boost::to_array( a ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } + + { + boost::array b = boost::to_array( f1().elems ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } + + { + boost::array b = boost::to_array( f2().elems ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } + +#if BOOST_CXX_VERSION >= 201103L + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + { + int a[] = { 1, 2, 3 }; + + boost::array b = boost::to_array( std::move( a ) ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } + + { + int const a[] = { 1, 2, 3 }; + + boost::array b = boost::to_array( std::move( a ) ); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } +#endif + +#if !BOOST_WORKAROUND(BOOST_GCC, < 40900) && !BOOST_WORKAROUND(BOOST_CLANG_VERSION, < 30800) + { + boost::array b = boost::to_array({ 1, 2, 3 }); + + BOOST_TEST_EQ( b[0], 1 ); + BOOST_TEST_EQ( b[1], 2 ); + BOOST_TEST_EQ( b[2], 3 ); + } +#endif + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920) + { + std::unique_ptr a[] = { {}, {}, {} }; + + boost::array, 3> b = boost::to_array( std::move( a ) ); + + (void)b; + } +#endif + +#endif + + return boost::report_errors(); +} diff --git a/test/to_array_test_cx.cpp b/test/to_array_test_cx.cpp new file mode 100644 index 00000000..e7f32c73 --- /dev/null +++ b/test/to_array_test_cx.cpp @@ -0,0 +1,32 @@ +// Copyright 2025 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined") + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +int main() +{ + { + constexpr int a[] = { 1, 2, 3, 4 }; + constexpr boost::array b = boost::to_array( a ); + + STATIC_ASSERT( b[0] == 1 ); + STATIC_ASSERT( b[1] == 2 ); + STATIC_ASSERT( b[2] == 3 ); + STATIC_ASSERT( b[3] == 4 ); + } +} + +#endif