/usr/include/boost/histogram/detail
Edit: /usr/include/boost/histogram/detail/span.hpp (9048B)
// 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
#ifdef __has_include
#if __has_include(
)
#include
#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
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
#include
#include
#include
#include
#include
namespace boost {
namespace histogram {
namespace detail {
namespace dtl = ::boost::histogram::detail;
static constexpr std::size_t dynamic_extent = ~static_cast(0);
template
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 span_base {
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 span : public span_base {
using base = span_base;
public:
using element_type = T;
using value_type = std::remove_cv_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;
using const_reverse_iterator = std::reverse_iterator;
static constexpr std::size_t extent = Extent;
using base::base;
constexpr span(pointer first, pointer last)
: span(first, static_cast(last - first)) {
assert(extent == dynamic_extent ||
static_cast(extent) == (last - first));
}
constexpr span(pointer ptr, index_type count) : base(ptr, count) {}
template
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 >
constexpr span(std::array& arr) noexcept : span(dtl::data(arr), N) {}
template >
constexpr span(const std::array& arr) noexcept
: span(dtl::data(arr), N) {}
template ()),
dtl::data(std::declval())),
pointer>::value> >
constexpr span(const Container& cont) : span(dtl::data(cont), dtl::size(cont)) {}
template ()),
dtl::data(std::declval())),
pointer>::value> >
constexpr span(Container& cont) : span(dtl::data(cont), dtl::size(cont)) {}
template ::value)> >
constexpr span(const span& s) noexcept : span(s.data(), s.size()) {}
template ::value)> >
constexpr span(span& 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
constexpr span first() const {
assert(Count <= base::size());
return span(base::data(), Count);
}
constexpr span first(std::size_t count) const {
assert(count <= base::size());
return span(base::data(), count);
}
template
constexpr span last() const {
assert(Count <= base::size());
return span(base::data() + base::size() - Count, Count);
}
constexpr span last(std::size_t count) const {
assert(count <= base::size());
return span(base::data() + base::size() - count, count);
}
template
constexpr span
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(base::data() + Offset,
Count == dynamic_extent ? base::size() - Offset : Count);
}
constexpr span 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(base::data() + offset, s);
}
};
} // namespace detail
} // namespace histogram
} // namespace boost
#endif
#include
#include
namespace boost {
namespace histogram {
namespace detail {
namespace dtl = ::boost::histogram::detail;
template
auto make_span(T* begin, T* end) {
return dtl::span{begin, end};
}
template
auto make_span(T* begin, std::size_t size) {
return dtl::span{begin, size};
}
template ()),
dtl::data(std::declval()))>
auto make_span(const Container& cont) {
return make_span(dtl::data(cont), dtl::size(cont));
}
template
auto make_span(T (&arr)[N]) {
return dtl::span(arr, N);
}
} // namespace detail
} // namespace histogram
} // namespace boost
#endif