Replace detail::span and detail::make_span with implementations in boost::core (#384)

* fix cmake build of benchmarks

* wip

* u

* u

* rename span.hpp to make_span.hpp

* missing file

* also replace make_span
This commit is contained in:
Hans Dembinski 2023-02-19 17:42:01 +01:00 committed by GitHub
parent 48ff00b642
commit 70b98302a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 34 additions and 267 deletions

View File

@ -7,8 +7,8 @@
#ifndef BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
#define BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
#include <boost/core/make_span.hpp>
#include <boost/core/nvp.hpp>
#include <boost/histogram/detail/span.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/mp11/function.hpp>
#include <boost/mp11/utility.hpp>
@ -48,8 +48,7 @@ struct array_wrapper {
ar);
},
[this](auto& ar) {
for (auto&& x : boost::histogram::detail::make_span(this->ptr, this->size))
ar& make_nvp("item", x);
for (auto&& x : make_span(this->ptr, this->size)) ar& make_nvp("item", x);
},
ar);
}

View File

@ -8,6 +8,8 @@
#define BOOST_HISTOGRAM_DETAIL_FILL_N_HPP
#include <algorithm>
#include <boost/core/make_span.hpp>
#include <boost/core/span.hpp>
#include <boost/histogram/axis/option.hpp>
#include <boost/histogram/axis/traits.hpp>
#include <boost/histogram/detail/axes.hpp>
@ -16,7 +18,6 @@
#include <boost/histogram/detail/linearize.hpp>
#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <boost/histogram/detail/optional_index.hpp>
#include <boost/histogram/detail/span.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/mp11/algorithm.hpp>
@ -260,7 +261,7 @@ void fill_n_1(const std::size_t offset, S& storage, A& axes, const std::size_t v
}
template <class A, class T, std::size_t N>
std::size_t get_total_size(const A& axes, const dtl::span<const T, N>& values) {
std::size_t get_total_size(const A& axes, const span<const T, N>& values) {
// supported cases (T = value type; CT = containter of T; V<T, CT, ...> = variant):
// - span<CT, N>: for any histogram, N == rank
// - span<V<T, CT>, N>: for any histogram, N == rank
@ -311,7 +312,7 @@ void fill_n_check_extra_args(std::size_t size, weight_type<T>&& w, Ts&&... ts) {
template <class S, class A, class T, std::size_t N, class... Us>
void fill_n(std::true_type, const std::size_t offset, S& storage, A& axes,
const dtl::span<const T, N> values, Us&&... us) {
const span<const T, N> values, Us&&... us) {
// supported cases (T = value type; CT = containter of T; V<T, CT, ...> = variant):
// - span<T, N>: only valid for 1D histogram, N > 1 allowed
// - span<CT, N>: for any histogram, N == rank

View File

@ -7,7 +7,7 @@
#ifndef BOOST_HISTOGRAM_DETAIL_REDUCE_COMMAND_HPP
#define BOOST_HISTOGRAM_DETAIL_REDUCE_COMMAND_HPP
#include <boost/histogram/detail/span.hpp>
#include <boost/core/span.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/throw_exception.hpp>
#include <cassert>

View File

@ -1,250 +0,0 @@
// Copyright 2019 Hans Dembinski
//
// 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)
#ifndef BOOST_HISTOGRAM_DETAIL_SPAN_HPP
#define BOOST_HISTOGRAM_DETAIL_SPAN_HPP
// to be replaced by boost::span
#include <array>
#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <cassert>
#include <initializer_list>
#include <iterator>
#include <type_traits>
namespace boost {
namespace histogram {
namespace detail {
namespace dtl = ::boost::histogram::detail;
static constexpr std::size_t dynamic_extent = ~static_cast<std::size_t>(0);
template <class T, std::size_t N>
class span_base {
public:
constexpr T* data() noexcept { return begin_; }
constexpr const T* data() const noexcept { return begin_; }
constexpr std::size_t size() const noexcept { return N; }
protected:
constexpr span_base(T* b, std::size_t s) noexcept : begin_(b) {
(void)s;
assert(N == s);
}
constexpr void set(T* b, std::size_t s) noexcept {
(void)s;
begin_ = b;
assert(N == s);
}
private:
T* begin_;
};
template <class T>
class span_base<T, dynamic_extent> {
public:
constexpr span_base() noexcept : begin_(nullptr), size_(0) {}
constexpr T* data() noexcept { return begin_; }
constexpr const T* data() const noexcept { return begin_; }
constexpr std::size_t size() const noexcept { return size_; }
protected:
constexpr span_base(T* b, std::size_t s) noexcept : begin_(b), size_(s) {}
constexpr void set(T* b, std::size_t s) noexcept {
begin_ = b;
size_ = s;
}
private:
T* begin_;
std::size_t size_;
};
template <class T, std::size_t Extent = dynamic_extent>
class span : public span_base<T, Extent> {
using base = span_base<T, Extent>;
public:
using element_type = T;
using value_type = std::remove_cv_t<T>;
using index_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr std::size_t extent = Extent;
using base::base;
constexpr span(pointer first, pointer last)
: span(first, static_cast<std::size_t>(last - first)) {
assert(extent == dynamic_extent ||
static_cast<difference_type>(extent) == (last - first));
}
constexpr span(pointer ptr, index_type count) : base(ptr, count) {}
template <std::size_t N>
constexpr span(element_type (&arr)[N]) noexcept : span(dtl::data(arr), N) {
static_assert(extent == dynamic_extent || extent == N, "static sizes do not match");
}
template <std::size_t N,
class = std::enable_if_t<(extent == dynamic_extent || extent == N)> >
constexpr span(std::array<value_type, N>& arr) noexcept : span(dtl::data(arr), N) {}
template <std::size_t N,
class = std::enable_if_t<(extent == dynamic_extent || extent == N)> >
constexpr span(const std::array<value_type, N>& arr) noexcept
: span(dtl::data(arr), N) {}
template <class Container, class = std::enable_if_t<std::is_convertible<
decltype(dtl::size(std::declval<const Container&>()),
dtl::data(std::declval<const Container&>())),
pointer>::value> >
constexpr span(const Container& cont) : span(dtl::data(cont), dtl::size(cont)) {}
template <class Container, class = std::enable_if_t<std::is_convertible<
decltype(dtl::size(std::declval<Container&>()),
dtl::data(std::declval<Container&>())),
pointer>::value> >
constexpr span(Container& cont) : span(dtl::data(cont), dtl::size(cont)) {}
template <class U, std::size_t N,
class = std::enable_if_t<((extent == dynamic_extent || extent == N) &&
std::is_convertible<U, element_type>::value)> >
constexpr span(const span<U, N>& s) noexcept : span(s.data(), s.size()) {}
template <class U, std::size_t N,
class = std::enable_if_t<((extent == dynamic_extent || extent == N) &&
std::is_convertible<U, element_type>::value)> >
constexpr span(span<U, N>& s) noexcept : span(s.data(), s.size()) {}
constexpr span(const span& other) noexcept = default;
constexpr iterator begin() { return base::data(); }
constexpr const_iterator begin() const { return base::data(); }
constexpr const_iterator cbegin() const { return base::data(); }
constexpr iterator end() { return base::data() + base::size(); }
constexpr const_iterator end() const { return base::data() + base::size(); }
constexpr const_iterator cend() const { return base::data() + base::size(); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return reverse_iterator(end()); }
const_reverse_iterator crbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return reverse_iterator(begin()); }
const_reverse_iterator crend() { return reverse_iterator(begin()); }
constexpr reference front() { return *base::data(); }
constexpr reference back() { return *(base::data() + base::size() - 1); }
constexpr reference operator[](index_type idx) const { return base::data()[idx]; }
constexpr std::size_t size_bytes() const noexcept {
return base::size() * sizeof(element_type);
}
constexpr bool empty() const noexcept { return base::size() == 0; }
template <std::size_t Count>
constexpr span<element_type, Count> first() const {
assert(Count <= base::size());
return span<element_type, Count>(base::data(), Count);
}
constexpr span<element_type, dynamic_extent> first(std::size_t count) const {
assert(count <= base::size());
return span<element_type, dynamic_extent>(base::data(), count);
}
template <std::size_t Count>
constexpr span<element_type, Count> last() const {
assert(Count <= base::size());
return span<element_type, Count>(base::data() + base::size() - Count, Count);
}
constexpr span<element_type, dynamic_extent> last(std::size_t count) const {
assert(count <= base::size());
return span<element_type, dynamic_extent>(base::data() + base::size() - count, count);
}
template <std::size_t Offset, std::size_t Count = dynamic_extent>
constexpr span<element_type,
(Count != dynamic_extent
? Count
: (extent != dynamic_extent ? extent - Offset : dynamic_extent))>
subspan() const {
assert(Offset <= base::size());
constexpr std::size_t E =
(Count != dynamic_extent
? Count
: (extent != dynamic_extent ? extent - Offset : dynamic_extent));
assert(E == dynamic_extent || E <= base::size());
return span<element_type, E>(base::data() + Offset,
Count == dynamic_extent ? base::size() - Offset : Count);
}
constexpr span<element_type, dynamic_extent> subspan(
std::size_t offset, std::size_t count = dynamic_extent) const {
assert(offset <= base::size());
const std::size_t s = count == dynamic_extent ? base::size() - offset : count;
assert(s <= base::size());
return span<element_type, dynamic_extent>(base::data() + offset, s);
}
};
} // namespace detail
} // namespace histogram
} // namespace boost
#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <utility>
namespace boost {
namespace histogram {
namespace detail {
namespace dtl = ::boost::histogram::detail;
template <class T>
auto make_span(T* begin, T* end) {
return dtl::span<T>{begin, end};
}
template <class T>
auto make_span(T* begin, std::size_t size) {
return dtl::span<T>{begin, size};
}
template <class Container, class = decltype(dtl::size(std::declval<Container>()),
dtl::data(std::declval<Container>()))>
auto make_span(const Container& cont) {
return make_span(dtl::data(cont), dtl::size(cont));
}
template <class T, std::size_t N>
auto make_span(T (&arr)[N]) {
return dtl::span<T, N>(arr, N);
}
} // namespace detail
} // namespace histogram
} // namespace boost
#endif

View File

@ -7,6 +7,7 @@
#ifndef BOOST_HISTOGRAM_HISTOGRAM_HPP
#define BOOST_HISTOGRAM_HISTOGRAM_HPP
#include <boost/core/make_span.hpp>
#include <boost/histogram/detail/accumulator_traits.hpp>
#include <boost/histogram/detail/argument_traits.hpp>
#include <boost/histogram/detail/axes.hpp>
@ -16,7 +17,6 @@
#include <boost/histogram/detail/index_translator.hpp>
#include <boost/histogram/detail/mutex_base.hpp>
#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <boost/histogram/detail/span.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/histogram/indexed.hpp>
@ -239,7 +239,7 @@ public:
"sample argument is missing but required by accumulator");
std::lock_guard<typename mutex_base::type> guard{mutex_base::get()};
detail::fill_n(mp11::mp_bool<(n_sample_args_expected == 0)>{}, offset_, storage_,
axes_, detail::make_span(args));
axes_, make_span(args));
}
/** Fill histogram with several values and weights at once.
@ -257,8 +257,7 @@ public:
std::is_convertible<std::tuple<>, typename acc_traits::args>::value;
std::lock_guard<typename mutex_base::type> guard{mutex_base::get()};
detail::fill_n(mp11::mp_bool<(weight_valid && sample_valid)>{}, offset_, storage_,
axes_, detail::make_span(args),
weight(detail::to_ptr_size(weights.value)));
axes_, make_span(args), weight(detail::to_ptr_size(weights.value)));
}
/** Fill histogram with several values and weights at once.
@ -289,7 +288,7 @@ public:
constexpr bool sample_valid =
std::is_convertible<sample_args_passed, typename acc_traits::args>::value;
detail::fill_n(mp11::mp_bool<(sample_valid)>{}, offset_, storage_, axes_,
detail::make_span(args), detail::to_ptr_size(sargs)...);
make_span(args), detail::to_ptr_size(sargs)...);
},
samples.value);
}
@ -321,7 +320,7 @@ public:
constexpr bool sample_valid =
std::is_convertible<sample_args_passed, typename acc_traits::args>::value;
detail::fill_n(mp11::mp_bool<(weight_valid && sample_valid)>{}, offset_,
storage_, axes_, detail::make_span(args),
storage_, axes_, make_span(args),
weight(detail::to_ptr_size(weights.value)),
detail::to_ptr_size(sargs)...);
},

View File

@ -9,6 +9,7 @@
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/make_span.hpp>
#include <boost/histogram/detail/array_wrapper.hpp>
#include <sstream>
#include <vector>
@ -24,7 +25,7 @@ struct dummy_array_wrapper {
std::size_t size;
template <class Archive>
void serialize(Archive& ar, unsigned /* version */) {
for (auto&& x : dtl::make_span(ptr, size)) ar& x;
for (auto&& x : boost::make_span(ptr, size)) ar& x;
}
};

View File

@ -7,13 +7,13 @@
#include <algorithm>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/core/make_span.hpp>
#include <boost/histogram/accumulators/weighted_sum.hpp>
#include <boost/histogram/axis/integer.hpp>
#include <boost/histogram/detail/common_type.hpp>
#include <boost/histogram/detail/counting_streambuf.hpp>
#include <boost/histogram/detail/index_translator.hpp>
#include <boost/histogram/detail/nonmember_container_access.hpp>
#include <boost/histogram/detail/span.hpp>
#include <boost/histogram/detail/sub_array.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/histogram/literals.hpp>
@ -126,6 +126,22 @@ int main() {
BOOST_TEST_EQ(count, 6);
}
// sub_array and make_span
{
dtl::sub_array<int, 2> a(2, 1);
a[1] = 2;
auto sp = boost::make_span(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 = boost::make_span(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<>;

View File

@ -1,7 +1,7 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/core/span.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>
@ -23,6 +23,7 @@ std::ostream& operator<<(std::ostream& os, const reduce_command&) { return os; }
using namespace boost::histogram::detail;
int main() {
using boost::span;
{
sub_array<int, 3> a = {1, 2};