-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Hans Dembinski <[email protected]>
- Loading branch information
1 parent
cd3e111
commit 90867e2
Showing
46 changed files
with
578 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright 2024 Ruggero Turra, 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_ACCUMULATORS_COLLECTOR_HPP | ||
#define BOOST_HISTOGRAM_ACCUMULATORS_COLLECTOR_HPP | ||
|
||
#include <algorithm> // for std::equal | ||
#include <boost/core/nvp.hpp> | ||
#include <boost/histogram/detail/detect.hpp> | ||
#include <boost/histogram/fwd.hpp> // for collector<> | ||
#include <initializer_list> | ||
#include <type_traits> | ||
|
||
namespace boost { | ||
namespace histogram { | ||
namespace accumulators { | ||
|
||
/** Collects samples. | ||
Input samples are stored in an internal container for later retrival, which stores the | ||
values consecutively in memory. The interface is designed to work with std::vector and | ||
other containers which implement the same API. | ||
Warning: The memory of the accumulator is unbounded. | ||
*/ | ||
template <class ContainerType> | ||
class collector { | ||
public: | ||
using container_type = ContainerType; | ||
using value_type = typename container_type::value_type; | ||
using allocator_type = typename container_type::allocator_type; | ||
using const_reference = typename container_type::const_reference; | ||
using iterator = typename container_type::iterator; | ||
using const_iterator = typename container_type::const_iterator; | ||
using size_type = typename container_type::size_type; | ||
using const_pointer = typename container_type::const_pointer; | ||
|
||
// make template only match if forwarding args to container is valid | ||
template <typename... Args, class = decltype(container_type(std::declval<Args>()...))> | ||
explicit collector(Args&&... args) : container_(std::forward<Args>(args)...) {} | ||
|
||
// make template only match if forwarding args to container is valid | ||
template <class T, typename... Args, class = decltype(container_type(std::initializer_list<T>(),std::declval<Args>()...))> | ||
explicit collector(std::initializer_list<T> list, Args&&... args) | ||
: container_(list, std::forward<Args>(args)...) {} | ||
|
||
/// Append sample x. | ||
void operator()(const_reference x) { container_.push_back(x); } | ||
|
||
/// Append samples from another collector. | ||
template <class C> | ||
collector& operator+=(const collector<C>& rhs) { | ||
container_.reserve(size() + rhs.size()); | ||
container_.insert(end(), rhs.begin(), rhs.end()); | ||
return *this; | ||
} | ||
|
||
/// Return true if collections are equal. | ||
/// | ||
/// Two collections are equal if they have the same number of elements | ||
/// which all compare equal. | ||
template <class Iterable, class = detail::is_iterable<Iterable>> | ||
bool operator==(const Iterable& rhs) const noexcept { | ||
return std::equal(begin(), end(), rhs.begin(), rhs.end()); | ||
} | ||
|
||
/// Return true if collections are not equal. | ||
template <class Iterable, class = detail::is_iterable<Iterable>> | ||
bool operator!=(const Iterable& rhs) const noexcept { | ||
return !operator==(rhs); | ||
} | ||
|
||
/// Return number of samples. | ||
size_type size() const noexcept { return container_.size(); } | ||
|
||
/// Return number of samples (alias for size()). | ||
size_type count() const noexcept { return container_.size(); } | ||
|
||
/// Return readonly iterator to start of collection. | ||
const const_iterator begin() const noexcept { return container_.begin(); } | ||
|
||
/// Return readonly iterator to end of collection. | ||
const const_iterator end() const noexcept { return container_.end(); } | ||
|
||
/// Return const reference to value at index. | ||
const_reference operator[](size_type idx) const noexcept { return container_[idx]; } | ||
|
||
/// Return pointer to internal memory. | ||
const_pointer data() const noexcept { return container_.data(); } | ||
|
||
allocator_type get_allocator() const { return container_.get_allocator(); } | ||
|
||
template <class Archive> | ||
void serialize(Archive& ar, unsigned version) { | ||
(void)version; | ||
ar& make_nvp("container", container_); | ||
} | ||
|
||
private: | ||
container_type container_; | ||
}; | ||
|
||
} // namespace accumulators | ||
} // namespace histogram | ||
} // namespace boost | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// 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_CHUNK_VECTOR_HPP | ||
#define BOOST_HISTOGRAM_DETAIL_CHUNK_VECTOR_HPP | ||
|
||
#include <boost/core/span.hpp> | ||
#include <boost/throw_exception.hpp> | ||
#include <stdexcept> | ||
#include <vector> | ||
|
||
namespace boost { | ||
namespace histogram { | ||
namespace detail { | ||
|
||
// Warning: this is not a proper container and is only used to | ||
// test the feasibility of using accumulators::collector with a | ||
// custom container type. If time permits, this will be expanded | ||
// into a proper container type. | ||
template <class ValueType> | ||
class chunk_vector { | ||
public: | ||
using base = std::vector<ValueType>; | ||
using allocator_type = typename base::allocator_type; | ||
using pointer = typename base::pointer; | ||
using const_pointer = typename base::const_pointer; | ||
using size_type = typename base::size_type; | ||
using const_reference = boost::span<const ValueType>; | ||
using reference = boost::span<ValueType>; | ||
// this is wrong and should make a copy; it is not a problem for | ||
// the current use-case, but a general purpose implementation cannot | ||
// violate concepts like this | ||
using value_type = const_reference; | ||
|
||
template <class Pointer> | ||
struct iterator_t { | ||
iterator_t& operator++() { | ||
ptr_ += chunk_; | ||
return *this; | ||
} | ||
|
||
iterator_t operator++(int) { | ||
iterator_t copy(*this); | ||
ptr_ += chunk_; | ||
return copy; | ||
} | ||
|
||
value_type operator*() const { return value_type(ptr_, ptr_ + chunk_); } | ||
|
||
Pointer ptr_; | ||
size_type chunk_; | ||
}; | ||
|
||
using iterator = iterator_t<pointer>; | ||
using const_iterator = iterator_t<const_pointer>; | ||
|
||
// this creates an empty chunk_vector | ||
explicit chunk_vector(size_type chunk, const allocator_type& alloc = {}) | ||
: chunk_(chunk), vec_(alloc) {} | ||
|
||
chunk_vector(std::initializer_list<value_type> list, size_type chunk, | ||
const allocator_type& alloc = {}) | ||
: chunk_(chunk), vec_(list, alloc) {} | ||
|
||
allocator_type get_allocator() noexcept(noexcept(allocator_type())) { | ||
return vec_.get_allocator(); | ||
} | ||
|
||
void push_back(const_reference x) { | ||
if (x.size() != chunk_) | ||
BOOST_THROW_EXCEPTION(std::runtime_error("argument has wrong size")); | ||
// we don't use std::vector::insert here to have amortized constant complexity | ||
for (auto&& elem : x) vec_.push_back(elem); | ||
} | ||
|
||
auto insert(const_iterator pos, const_iterator o_begin, const_iterator o_end) { | ||
if (std::distance(o_begin, o_end) % chunk_ == 0) | ||
BOOST_THROW_EXCEPTION(std::runtime_error("argument has wrong size")); | ||
return vec_.insert(pos, o_begin, o_end); | ||
} | ||
|
||
const_iterator begin() const noexcept { return {vec_.data(), chunk_}; } | ||
const_iterator end() const noexcept { return {vec_.data() + vec_.size(), chunk_}; } | ||
|
||
value_type operator[](size_type idx) const noexcept { | ||
return {vec_.data() + idx * chunk_, vec_.data() + (idx + 1) * chunk_}; | ||
} | ||
|
||
size_type size() const noexcept { return vec_.size() / chunk_; } | ||
|
||
private: | ||
size_type chunk_; | ||
base vec_; | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace histogram | ||
} // namespace boost | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.