mirror of
https://github.com/boostorg/histogram.git
synced 2026-01-19 04:12:12 +00:00
fix sub_array and span in C++20 (#368)
This commit is contained in:
4
.github/workflows/cov.yml
vendored
4
.github/workflows/cov.yml
vendored
@@ -14,6 +14,10 @@ env:
|
||||
B2_OPTS: -q -j2 warnings-as-errors=on
|
||||
GCC_VERSION: 11
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
cov:
|
||||
runs-on: macos-11
|
||||
|
||||
4
.github/workflows/fast.yml
vendored
4
.github/workflows/fast.yml
vendored
@@ -20,6 +20,10 @@ on:
|
||||
- 'tools/**'
|
||||
- '*.md'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
cmake:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
4
.github/workflows/slow.yml
vendored
4
.github/workflows/slow.yml
vendored
@@ -10,6 +10,10 @@ on:
|
||||
- 'tools/**'
|
||||
- '*.md'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
B2_OPTS: -q -j2 warnings-as-errors=on
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
4
.github/workflows/superproject_cmake.yml
vendored
4
.github/workflows/superproject_cmake.yml
vendored
@@ -6,6 +6,10 @@ on:
|
||||
- master
|
||||
- develop
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
|
||||
@@ -28,8 +28,10 @@ function(add_benchmark NAME)
|
||||
add_executable(${NAME} ${SOURCE})
|
||||
target_include_directories(${NAME} PRIVATE ${__INCLUDE_DIRECTORIES})
|
||||
target_link_libraries(${NAME} PRIVATE Boost::histogram Boost::math benchmark_main ${__LINK_LIBRARIES})
|
||||
target_compile_options(${NAME} PRIVATE -DNDEBUG -O3 -march=native -funsafe-math-optimizations ${__COMPILE_OPTIONS})
|
||||
|
||||
target_compile_options(${NAME} PRIVATE -DNDEBUG -O3 -funsafe-math-optimizations ${__COMPILE_OPTIONS})
|
||||
if (NOT DARWIN)
|
||||
target_compile_options(${NAME} PRIVATE -march=native)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
add_benchmark(axis_size)
|
||||
|
||||
@@ -50,12 +50,12 @@ static auto hist = make_histogram_with(DSTS(), axis::regular<>());
|
||||
|
||||
static void AtomicStorage(benchmark::State& state) {
|
||||
init.lock();
|
||||
if (state.thread_index == 0) {
|
||||
if (state.thread_index() == 0) {
|
||||
const unsigned nbins = state.range(0);
|
||||
hist = make_histogram_with(DSTS(), axis::regular<>(nbins, 0, 1));
|
||||
}
|
||||
init.unlock();
|
||||
std::default_random_engine gen(state.thread_index);
|
||||
std::default_random_engine gen(state.thread_index());
|
||||
std::uniform_real_distribution<> dis(0, 1);
|
||||
for (auto _ : state) {
|
||||
// simulate some work
|
||||
|
||||
@@ -7,31 +7,6 @@
|
||||
#ifndef BOOST_HISTOGRAM_DETAIL_SPAN_HPP
|
||||
#define BOOST_HISTOGRAM_DETAIL_SPAN_HPP
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include(<version>)
|
||||
#include <version>
|
||||
#ifdef __cpp_lib_span
|
||||
#if __cpp_lib_span >= 201902
|
||||
#define BOOST_HISTOGRAM_DETAIL_HAS_STD_SPAN
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HISTOGRAM_DETAIL_HAS_STD_SPAN
|
||||
|
||||
#include <span>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
using std::span;
|
||||
} // namespace detail
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#else // C++17 span not available, so we use our implementation
|
||||
|
||||
// to be replaced by boost::span
|
||||
|
||||
#include <array>
|
||||
@@ -238,8 +213,6 @@ public:
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/histogram/detail/nonmember_container_access.hpp>
|
||||
#include <utility>
|
||||
|
||||
|
||||
@@ -15,15 +15,17 @@ namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
|
||||
// Like std::array, but allows to use less than maximum capacity.
|
||||
// Cannot inherit from std::array, since this confuses span.
|
||||
template <class T, std::size_t N>
|
||||
class sub_array {
|
||||
constexpr bool swap_element_is_noexcept() noexcept {
|
||||
static constexpr bool swap_element_is_noexcept() noexcept {
|
||||
using std::swap;
|
||||
return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using element_type = T;
|
||||
using size_type = std::size_t;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
@@ -42,6 +44,12 @@ public:
|
||||
fill(value);
|
||||
}
|
||||
|
||||
sub_array(std::initializer_list<T> il) noexcept(
|
||||
std::is_nothrow_assignable<T, const_reference>::value)
|
||||
: sub_array(il.size()) {
|
||||
std::copy(il.begin(), il.end(), data_);
|
||||
}
|
||||
|
||||
reference at(size_type pos) noexcept {
|
||||
if (pos >= size()) BOOST_THROW_EXCEPTION(std::out_of_range{"pos is out of range"});
|
||||
return data_[pos];
|
||||
@@ -70,10 +78,7 @@ public:
|
||||
iterator end() noexcept { return begin() + size_; }
|
||||
const_iterator end() const noexcept { return begin() + size_; }
|
||||
|
||||
const_iterator cbegin() noexcept { return data_; }
|
||||
const_iterator cbegin() const noexcept { return data_; }
|
||||
|
||||
const_iterator cend() noexcept { return cbegin() + size_; }
|
||||
const_iterator cend() const noexcept { return cbegin() + size_; }
|
||||
|
||||
constexpr size_type max_size() const noexcept { return N; }
|
||||
@@ -87,17 +92,20 @@ public:
|
||||
|
||||
void swap(sub_array& other) noexcept(swap_element_is_noexcept()) {
|
||||
using std::swap;
|
||||
for (auto i = begin(), j = other.begin(); i != end(); ++i, ++j) swap(*i, *j);
|
||||
const size_type s = (std::max)(size(), other.size());
|
||||
for (auto i = begin(), j = other.begin(), end = begin() + s; i != end; ++i, ++j)
|
||||
swap(*i, *j);
|
||||
swap(size_, other.size_);
|
||||
}
|
||||
|
||||
private:
|
||||
size_type size_ = 0;
|
||||
value_type data_[N];
|
||||
element_type data_[N];
|
||||
};
|
||||
|
||||
template <class T, std::size_t N>
|
||||
bool operator==(const sub_array<T, N>& a, const sub_array<T, N>& b) noexcept {
|
||||
return std::equal(a.begin(), a.end(), b.begin());
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end());
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
|
||||
@@ -73,6 +73,7 @@ boost_test(TYPE run SOURCES detail_operators_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_relaxed_equal_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_replace_type_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_safe_comparison_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_sub_array_and_span_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_static_if_test.cpp)
|
||||
boost_test(TYPE run SOURCES detail_tuple_slice_test.cpp)
|
||||
boost_test(TYPE run SOURCES histogram_custom_axis_test.cpp)
|
||||
|
||||
@@ -77,6 +77,7 @@ alias cxx14 :
|
||||
[ run detail_replace_type_test.cpp ]
|
||||
[ run detail_safe_comparison_test.cpp ]
|
||||
[ run detail_static_if_test.cpp ]
|
||||
[ run detail_sub_array_and_span_test.cpp ]
|
||||
[ run detail_tuple_slice_test.cpp ]
|
||||
[ run histogram_custom_axis_test.cpp ]
|
||||
[ run histogram_dynamic_test.cpp ]
|
||||
|
||||
@@ -126,22 +126,6 @@ int main() {
|
||||
BOOST_TEST_EQ(count, 6);
|
||||
}
|
||||
|
||||
// sub_array and span
|
||||
{
|
||||
dtl::sub_array<int, 2> a(2, 1);
|
||||
a[1] = 2;
|
||||
auto sp = dtl::span<int>(a);
|
||||
BOOST_TEST_EQ(sp.size(), 2);
|
||||
BOOST_TEST_EQ(sp.front(), 1);
|
||||
BOOST_TEST_EQ(sp.back(), 2);
|
||||
|
||||
const auto& ca = a;
|
||||
auto csp = dtl::span<const int>(ca);
|
||||
BOOST_TEST_EQ(csp.size(), 2);
|
||||
BOOST_TEST_EQ(csp.front(), 1);
|
||||
BOOST_TEST_EQ(csp.back(), 2);
|
||||
}
|
||||
|
||||
// index_translator
|
||||
{
|
||||
using I = axis::integer<>;
|
||||
|
||||
87
test/detail_sub_array_and_span_test.cpp
Normal file
87
test/detail_sub_array_and_span_test.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/histogram/detail/nonmember_container_access.hpp>
|
||||
#include <boost/histogram/detail/reduce_command.hpp>
|
||||
#include <boost/histogram/detail/span.hpp>
|
||||
#include <boost/histogram/detail/sub_array.hpp>
|
||||
#include <initializer_list>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include "throw_exception.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
template <class T, std::size_t N>
|
||||
std::ostream& operator<<(std::ostream& os, const sub_array<T, N>&) {
|
||||
return os;
|
||||
}
|
||||
std::ostream& operator<<(std::ostream& os, const reduce_command&) { return os; }
|
||||
} // namespace detail
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
using namespace boost::histogram::detail;
|
||||
|
||||
int main() {
|
||||
|
||||
{
|
||||
sub_array<int, 3> a = {1, 2};
|
||||
|
||||
BOOST_TEST_EQ(a.size(), 2);
|
||||
BOOST_TEST_EQ(a.max_size(), 3);
|
||||
BOOST_TEST_EQ(a.at(0), 1);
|
||||
BOOST_TEST_EQ(a.at(1), 2);
|
||||
|
||||
sub_array<int, 3> b = {1, 2};
|
||||
BOOST_TEST_EQ(a, b);
|
||||
|
||||
sub_array<int, 3> c = {1, 2, 3};
|
||||
BOOST_TEST_NE(a, c);
|
||||
|
||||
sub_array<int, 3> d = {2, 2};
|
||||
BOOST_TEST_NE(a, d);
|
||||
|
||||
auto sp = span<int>(a);
|
||||
BOOST_TEST_EQ(sp.size(), 2);
|
||||
BOOST_TEST_EQ(sp.front(), 1);
|
||||
BOOST_TEST_EQ(sp.back(), 2);
|
||||
|
||||
const auto& ca = a;
|
||||
auto csp = span<const int>(ca);
|
||||
BOOST_TEST_EQ(csp.size(), 2);
|
||||
BOOST_TEST_EQ(csp.front(), 1);
|
||||
BOOST_TEST_EQ(csp.back(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
sub_array<int, 2> a(2, 1);
|
||||
sub_array<int, 2> b(1, 2);
|
||||
std::swap(a, b);
|
||||
|
||||
BOOST_TEST_EQ(a.size(), 1);
|
||||
BOOST_TEST_EQ(b.size(), 2);
|
||||
BOOST_TEST_EQ(a[0], 2);
|
||||
BOOST_TEST_EQ(b[0], 1);
|
||||
BOOST_TEST_EQ(b[1], 1);
|
||||
}
|
||||
|
||||
{
|
||||
const std::initializer_list<int> a = {1, 2};
|
||||
auto sp = span<const int>(a);
|
||||
BOOST_TEST_EQ(sp.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
const sub_array<reduce_command, 3> a(2);
|
||||
auto sp = span<const reduce_command>(a);
|
||||
BOOST_TEST_EQ(sp.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
const std::initializer_list<reduce_command> a = {reduce_command{}};
|
||||
auto sp = span<const reduce_command>(a);
|
||||
BOOST_TEST_EQ(sp.size(), 1);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user