2
0
mirror of https://github.com/boostorg/compat.git synced 2026-01-24 17:52:32 +00:00

21 Commits

Author SHA1 Message Date
Peter Dimov
1a8bb0b574 Update revision history 2024-10-04 13:43:06 +03:00
Peter Dimov
c18e5f2276 Move MSVC workarounds from test/Jamfile to to_array_rvalue_test.cpp 2024-10-04 13:26:50 +03:00
Anarthal (Rubén Pérez)
d2d5cbe094 Added to_array (#14)
* Added to_array

* Suppress unused warnings

* Fix unused warnings (2)

* Workaround msvc 14.0 bug

* Workaround MSVC problems with moving arrays

* MSVC workaround in constexpr test

* Further MSVC fixes

* Disable rvalue tests for MSVC 14.0

* Incorrect argument spec

* constexpr checks

* const test

* Disable rvalues for msvc 14.1

* Docs

* Added more const tests

* Correct static_asserts

* Update type requirements in docs

* Corrected return types and conditions

* Doc updates
2024-10-04 13:06:44 +03:00
Peter Dimov
c49f822b2e Update .drone.jsonnet 2024-08-21 10:49:04 +03:00
Peter Dimov
889d2608e6 Add VERBATIM to add_custom_target 2024-08-20 21:06:26 +03:00
Peter Dimov
787a5dd4d1 Update build.jam 2024-08-20 20:56:20 +03:00
Rene Rivera
a6520ef2e1 Sync from upstream. 2024-07-25 17:20:02 -05:00
Rene Rivera
0d2593326f Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:24 -05:00
Peter Dimov
4abae7082a Update ci.yml 2024-07-22 02:15:35 +03:00
Peter Dimov
d802b97ba8 Update .drone.jsonnet 2024-07-22 02:03:00 +03:00
Rene Rivera
e6d2faa267 Sync from upstream. 2024-07-12 08:55:45 -05:00
Rene Rivera
438e0fbbf3 Bump B2 require to 5.2 2024-06-14 11:33:55 -05:00
Rene Rivera
df5cd71735 Add requires-b2 check to top-level build file. 2024-05-05 09:00:00 -05:00
Rene Rivera
6f8c2fe8c1 Add missing import-search for cconfig/predef checks. 2024-05-04 23:28:15 -05:00
Rene Rivera
e5f0043abc Sync from upstream. 2024-04-28 20:36:12 -05:00
Rene Rivera
d5cf9802bd Add new lib dependencies. 2024-04-25 22:12:11 -05:00
Rene Rivera
28496a6a01 Sync from upstream. 2024-04-20 15:34:30 -05:00
Rene Rivera
ed8837a4ff Sync from upstream. 2024-04-10 07:58:31 -05:00
Rene Rivera
7fc7795d6b Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:15:58 -05:00
Rene Rivera
0598dd0688 Sync from upstream. 2024-03-23 07:58:05 -05:00
Rene Rivera
c511487e78 Make the library modular usable. 2024-03-11 08:27:02 -05:00
12 changed files with 352 additions and 18 deletions

View File

@@ -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",
),

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

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

View 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