mirror of
https://github.com/boostorg/compat.git
synced 2026-01-24 17:52:32 +00:00
Compare commits
21 Commits
boost-1.86
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a8bb0b574 | ||
|
|
c18e5f2276 | ||
|
|
d2d5cbe094 | ||
|
|
c49f822b2e | ||
|
|
889d2608e6 | ||
|
|
787a5dd4d1 | ||
|
|
a6520ef2e1 | ||
|
|
0d2593326f | ||
|
|
4abae7082a | ||
|
|
d802b97ba8 | ||
|
|
e6d2faa267 | ||
|
|
438e0fbbf3 | ||
|
|
df5cd71735 | ||
|
|
6f8c2fe8c1 | ||
|
|
e5f0043abc | ||
|
|
d5cf9802bd | ||
|
|
28496a6a01 | ||
|
|
ed8837a4ff | ||
|
|
7fc7795d6b | ||
|
|
0598dd0688 | ||
|
|
c511487e78 |
@@ -32,6 +32,8 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'uname -a',
|
||||
'echo $DRONE_STAGE_MACHINE',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
@@ -99,7 +101,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.8 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"g++-4.8-multilib",
|
||||
),
|
||||
|
||||
@@ -123,21 +125,21 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 ARM64 UBSAN",
|
||||
"Linux 20.04 GCC 9* ARM64 UBSAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + ubsan,
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 ARM64 ASAN",
|
||||
"Linux 20.04 GCC 9* ARM64 ASAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + asan,
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9 S390x UBSAN",
|
||||
"Linux 20.04 GCC 9* S390x UBSAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + ubsan,
|
||||
arch="s390x",
|
||||
@@ -151,23 +153,37 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 GCC 13 32/64 UBSAN",
|
||||
"Linux 23.04 GCC 13 32/64",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' } + ubsan,
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 GCC 13 32/64 ASAN",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' } + asan,
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32/64",
|
||||
"Linux 24.04 GCC 14 32 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
|
||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -176,6 +176,10 @@ jobs:
|
||||
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
|
||||
|
||||
22
build.jam
Normal file
22
build.jam
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright 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/compat ;
|
||||
|
||||
explicit
|
||||
[ alias boost_compat : : : : <include>include <library>$(boost_dependencies) ]
|
||||
[ alias all : boost_compat test ]
|
||||
;
|
||||
|
||||
call-if : boost-library compat
|
||||
;
|
||||
@@ -8,6 +8,10 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
# Revision History
|
||||
:idprefix: changelog_
|
||||
|
||||
## Changes in 1.87.0
|
||||
|
||||
* Added `to_array.hpp` (contributed by Ruben Perez Hidalgo.)
|
||||
|
||||
## Changes in 1.86.0
|
||||
|
||||
* Added `bind_front.hpp`, `bind_back.hpp`, `invoke.hpp`, `mem_fn.hpp`, `integer_sequence.hpp` and `type_traits.hpp`.
|
||||
|
||||
@@ -12,4 +12,5 @@ include::invoke.adoc[]
|
||||
include::latch.adoc[]
|
||||
include::mem_fn.adoc[]
|
||||
include::shared_lock.adoc[]
|
||||
include::to_array.adoc[]
|
||||
include::type_traits.adoc[]
|
||||
|
||||
72
doc/compat/to_array.adoc
Normal file
72
doc/compat/to_array.adoc
Normal file
@@ -0,0 +1,72 @@
|
||||
////
|
||||
Copyright 2024 Ruben Perez Hidalgo
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#to_array]
|
||||
# <boost/compat/to_array.hpp>
|
||||
:idprefix: ref_to_array_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/to_array.hpp>` implements, in a portable way, the C++20
|
||||
`std::to_array` function, present in the `<array>` header.
|
||||
|
||||
`to_array` creates a `std::array` from a single-dimensional C array,
|
||||
performing an element-wise copy or move.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
int input [] = {1, 2, 3};
|
||||
std::array<int, 3> output = boost::compat::to_array(input);
|
||||
assert((
|
||||
output == std::array<int, 3>{{1, 2, 3}}
|
||||
));
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```cpp
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&a)[N]);
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## to_array
|
||||
|
||||
```cpp
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Creates an array of `N` elements by copying elements in `a`.
|
||||
For every `i` in `0, ..., N-1`, copy-initializes the i-th element
|
||||
in the output array from `a[i]`.
|
||||
Type requirements:;; `std::is_constructible_v<remove_cv_t<T>, T&> && !std::is_array_v<T>`.
|
||||
Otherwise, the overload is ill-formed.
|
||||
|
||||
|
||||
```cpp
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cvref_t<T>, N> to_array(T (&a)[N]);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Creates an array of `N` elements by moving elements in `a`.
|
||||
For every `i` in `0, ..., N-1`, move-initializes the i-th element
|
||||
in the output array from `std::move(a[i])`.
|
||||
Type requirements:;; `std::is_constructible_v<remove_cv_t<T>, T&&> && !std::is_array_v<T>`.
|
||||
Otherwise, the overload is ill-formed.
|
||||
60
include/boost/compat/to_array.hpp
Normal file
60
include/boost/compat/to_array.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Ruben Perez Hidalgo
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/integer_sequence.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T, std::size_t N, std::size_t... I>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array_lvalue(T (&a)[N], index_sequence<I...>)
|
||||
{
|
||||
return {{a[I]...}};
|
||||
}
|
||||
|
||||
template <class T, std::size_t N, std::size_t... I>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array_rvalue(T (&&a)[N], index_sequence<I...>)
|
||||
{
|
||||
return {{std::move(a[I])...}};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&a)[N])
|
||||
{
|
||||
static_assert(
|
||||
std::is_constructible<remove_cv_t<T>, T&>::value,
|
||||
"This overload requires the resulting element type to be constructible from T&"
|
||||
);
|
||||
static_assert(!std::is_array<T>::value, "to_array does not work for multi-dimensional C arrays");
|
||||
return detail::to_array_lvalue(a, make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N])
|
||||
{
|
||||
static_assert(
|
||||
std::is_constructible<remove_cv_t<T>, T&&>::value,
|
||||
"This overload requires the resulting element type to be constructible from T&&"
|
||||
);
|
||||
static_assert(!std::is_array<T>::value, "to_array does not work for multi-dimensional C arrays");
|
||||
return detail::to_array_rvalue(static_cast<T(&&)[N]>(a), make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
@@ -4,7 +4,8 @@
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
import testing ;
|
||||
import ../../config/checks/config : requires ;
|
||||
import-search /boost/config/checks ;
|
||||
import config : requires ;
|
||||
|
||||
project
|
||||
: default-build
|
||||
@@ -21,6 +22,9 @@ project
|
||||
<toolset>gcc:<warnings-as-errors>on
|
||||
<toolset>clang:<warnings-as-errors>on
|
||||
|
||||
<library>/boost/core//boost_core
|
||||
<library>/boost/mp11//boost_mp11
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81601
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92397
|
||||
@@ -108,3 +112,6 @@ run function_ref_mfn_test.cpp ;
|
||||
run function_ref_fn_noexcept_test.cpp ;
|
||||
run function_ref_mfn_noexcept_test.cpp ;
|
||||
run function_ref_obj_noexcept_test.cpp ;
|
||||
|
||||
run to_array_lvalue_test.cpp ;
|
||||
run to_array_rvalue_test.cpp ;
|
||||
|
||||
@@ -14,4 +14,4 @@ target_link_libraries(quick Boost::compat)
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
|
||||
@@ -18,4 +18,4 @@ target_link_libraries(quick Boost::compat)
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
|
||||
60
test/to_array_lvalue_test.cpp
Normal file
60
test/to_array_lvalue_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 Ruben Perez Hidalgo.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/to_array.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
// regular C array
|
||||
int input[] = {1, 2};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
}
|
||||
{
|
||||
// regular C array, const
|
||||
const int input[] = {1, 2};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
}
|
||||
{
|
||||
// values not moved
|
||||
const std::vector<int> vec{1, 2};
|
||||
std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
{
|
||||
// const values work
|
||||
const std::vector<int> vec{1, 2};
|
||||
const std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
{
|
||||
// constexpr check
|
||||
constexpr int input[] = {1, 2, 3};
|
||||
constexpr auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), const std::array<int, 3>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
BOOST_TEST_EQ(output[2], 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
88
test/to_array_rvalue_test.cpp
Normal file
88
test/to_array_rvalue_test.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2024 Ruben Perez Hidalgo.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/to_array.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
// regular C array
|
||||
int input[] = {5, 6};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 5);
|
||||
BOOST_TEST_EQ(output[1], 6);
|
||||
}
|
||||
{
|
||||
// regular C array, const
|
||||
const int input[] = {5, 6};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 5);
|
||||
BOOST_TEST_EQ(output[1], 6);
|
||||
}
|
||||
{
|
||||
// values moved
|
||||
const std::vector<int> vec{1, 2};
|
||||
std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
BOOST_TEST(input[0].empty()); // input left in a moved-from state
|
||||
#endif
|
||||
}
|
||||
{
|
||||
// const values work (although they don't result in an effective move)
|
||||
const std::vector<int> vec{1, 2};
|
||||
const std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
{
|
||||
// move-only types work
|
||||
std::unique_ptr<int> input[] = {std::unique_ptr<int>{new int(42)}};
|
||||
int* ptr = input[0].get();
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::unique_ptr<int>, 1>>::value, "");
|
||||
BOOST_TEST_EQ(output[0].get(), ptr);
|
||||
BOOST_TEST_EQ(input[0].get(), nullptr); // input left in a moved-from state
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// constexpr check
|
||||
constexpr int input[] = {1, 2, 3};
|
||||
constexpr auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), const std::array<int, 3>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
BOOST_TEST_EQ(output[2], 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user