Skip to content

Commit

Permalink
fix sub_array and span in C++20 (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
HDembinski authored Oct 3, 2022
1 parent 1c9077a commit 25608fe
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 55 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/cov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/fast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
- 'tools/**'
- '*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

jobs:
cmake:
runs-on: ${{ matrix.os }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/slow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/superproject_cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
- master
- develop

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

jobs:
build:
runs-on: macos-latest
Expand Down
6 changes: 4 additions & 2 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions benchmark/histogram_parallel_filling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 0 additions & 27 deletions include/boost/histogram/detail/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -238,8 +213,6 @@ class span : public span_base<T, Extent> {
} // namespace histogram
} // namespace boost

#endif

#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <utility>

Expand Down
24 changes: 16 additions & 8 deletions include/boost/histogram/detail/sub_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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&;
Expand All @@ -42,6 +44,12 @@ class sub_array {
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];
Expand Down Expand Up @@ -70,10 +78,7 @@ class sub_array {
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; }
Expand All @@ -87,17 +92,20 @@ class sub_array {

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>
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
Expand Down
16 changes: 0 additions & 16 deletions test/detail_misc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<>;
Expand Down
87 changes: 87 additions & 0 deletions test/detail_sub_array_and_span_test.cpp
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit 25608fe

Please sign in to comment.