update boost on linux
This commit is contained in:
184
linx64/include/boost/histogram/axis/category.hpp
Normal file
184
linx64/include/boost/histogram/axis/category.hpp
Normal file
@@ -0,0 +1,184 @@
|
||||
// Copyright 2015-2018 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_AXIS_CATEGORY_HPP
|
||||
#define BOOST_HISTOGRAM_AXIS_CATEGORY_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/histogram/axis/iterator.hpp>
|
||||
#include <boost/histogram/axis/option.hpp>
|
||||
#include <boost/histogram/detail/compressed_pair.hpp>
|
||||
#include <boost/histogram/detail/meta.hpp>
|
||||
#include <boost/histogram/fwd.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
/**
|
||||
Maps at a set of unique values to bin indices.
|
||||
|
||||
The axis maps a set of values to bins, following the order of arguments in the
|
||||
constructor. The optional overflow bin for this axis counts input values that
|
||||
are not part of the set. Binning has O(N) complexity, but with a very small
|
||||
factor. For small N (the typical use case) it beats other kinds of lookup.
|
||||
|
||||
@tparam Value input value type, must be equal-comparable.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
@tparam Allocator allocator to use for dynamic memory management.
|
||||
|
||||
The options `underflow` and `circular` are not allowed. The options `growth`
|
||||
and `overflow` are mutually exclusive.
|
||||
*/
|
||||
template <class Value, class MetaData, class Options, class Allocator>
|
||||
class category : public iterator_mixin<category<Value, MetaData, Options, Allocator>> {
|
||||
using value_type = Value;
|
||||
using metadata_type = detail::replace_default<MetaData, std::string>;
|
||||
using options_type = detail::replace_default<Options, option::overflow_t>;
|
||||
static_assert(!options_type::test(option::underflow),
|
||||
"category axis cannot have underflow");
|
||||
static_assert(!options_type::test(option::circular),
|
||||
"category axis cannot be circular");
|
||||
static_assert(!options_type::test(option::growth) ||
|
||||
!options_type::test(option::overflow),
|
||||
"growing category axis cannot have overflow");
|
||||
using allocator_type = Allocator;
|
||||
using vector_type = std::vector<value_type, allocator_type>;
|
||||
|
||||
public:
|
||||
explicit category(allocator_type alloc = {}) : vec_meta_(vector_type(alloc)) {}
|
||||
|
||||
/** Construct from iterator range of unique values.
|
||||
*
|
||||
* \param begin begin of category range of unique values.
|
||||
* \param end end of category range of unique values.
|
||||
* \param meta description of the axis.
|
||||
* \param alloc allocator instance to use.
|
||||
*/
|
||||
template <class It, class = detail::requires_iterator<It>>
|
||||
category(It begin, It end, metadata_type meta = {}, allocator_type alloc = {})
|
||||
: vec_meta_(vector_type(begin, end, alloc), std::move(meta)) {
|
||||
if (size() == 0) BOOST_THROW_EXCEPTION(std::invalid_argument("bins > 0 required"));
|
||||
}
|
||||
|
||||
/** Construct axis from iterable sequence of unique values.
|
||||
*
|
||||
* \param iterable sequence of unique values.
|
||||
* \param meta description of the axis.
|
||||
* \param alloc allocator instance to use.
|
||||
*/
|
||||
template <class C, class = detail::requires_iterable<C>>
|
||||
category(const C& iterable, metadata_type meta = {}, allocator_type alloc = {})
|
||||
: category(std::begin(iterable), std::end(iterable), std::move(meta),
|
||||
std::move(alloc)) {}
|
||||
|
||||
/** Construct axis from an initializer list of unique values.
|
||||
*
|
||||
* \param list `std::initializer_list` of unique values.
|
||||
* \param meta description of the axis.
|
||||
* \param alloc allocator instance to use.
|
||||
*/
|
||||
template <class U>
|
||||
category(std::initializer_list<U> list, metadata_type meta = {},
|
||||
allocator_type alloc = {})
|
||||
: category(list.begin(), list.end(), std::move(meta), std::move(alloc)) {}
|
||||
|
||||
/// Constructor used by algorithm::reduce to shrink and rebin.
|
||||
category(const category& src, index_type begin, index_type end, unsigned merge)
|
||||
: category(src.vec_meta_.first().begin() + begin,
|
||||
src.vec_meta_.first().begin() + end, src.metadata()) {
|
||||
if (merge > 1)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("cannot merge bins for category axis"));
|
||||
}
|
||||
|
||||
/// Return index for value argument.
|
||||
index_type index(const value_type& x) const noexcept {
|
||||
const auto beg = vec_meta_.first().begin();
|
||||
const auto end = vec_meta_.first().end();
|
||||
return static_cast<index_type>(std::distance(beg, std::find(beg, end, x)));
|
||||
}
|
||||
|
||||
/// Returns index and shift (if axis has grown) for the passed argument.
|
||||
auto update(const value_type& x) {
|
||||
const auto i = index(x);
|
||||
if (i < size()) return std::make_pair(i, 0);
|
||||
vec_meta_.first().emplace_back(x);
|
||||
return std::make_pair(i, -1);
|
||||
}
|
||||
|
||||
/// Return value for index argument.
|
||||
/// Throws `std::out_of_range` if the index is out of bounds.
|
||||
decltype(auto) value(index_type idx) const {
|
||||
if (idx < 0 || idx >= size())
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("category index out of range"));
|
||||
return vec_meta_.first()[idx];
|
||||
}
|
||||
|
||||
/// Return value for index argument.
|
||||
decltype(auto) bin(index_type idx) const noexcept { return value(idx); }
|
||||
|
||||
/// Returns the number of bins, without over- or underflow.
|
||||
index_type size() const noexcept {
|
||||
return static_cast<index_type>(vec_meta_.first().size());
|
||||
}
|
||||
/// Returns the options.
|
||||
static constexpr unsigned options() noexcept { return options_type::value; }
|
||||
/// Returns reference to metadata.
|
||||
metadata_type& metadata() noexcept { return vec_meta_.second(); }
|
||||
/// Returns reference to const metadata.
|
||||
const metadata_type& metadata() const noexcept { return vec_meta_.second(); }
|
||||
|
||||
template <class V, class M, class O, class A>
|
||||
bool operator==(const category<V, M, O, A>& o) const noexcept {
|
||||
const auto& a = vec_meta_.first();
|
||||
const auto& b = o.vec_meta_.first();
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end()) &&
|
||||
detail::relaxed_equal(metadata(), o.metadata());
|
||||
}
|
||||
|
||||
template <class V, class M, class O, class A>
|
||||
bool operator!=(const category<V, M, O, A>& o) const noexcept {
|
||||
return !operator==(o);
|
||||
}
|
||||
|
||||
auto get_allocator() const { return vec_meta_.first().get_allocator(); }
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive&, unsigned);
|
||||
|
||||
private:
|
||||
detail::compressed_pair<vector_type, metadata_type> vec_meta_;
|
||||
|
||||
template <class V, class M, class O, class A>
|
||||
friend class category;
|
||||
};
|
||||
|
||||
#if __cpp_deduction_guides >= 201606
|
||||
|
||||
template <class T>
|
||||
category(std::initializer_list<T>)->category<T>;
|
||||
|
||||
category(std::initializer_list<const char*>)->category<std::string>;
|
||||
|
||||
template <class T>
|
||||
category(std::initializer_list<T>, const char*)->category<T>;
|
||||
|
||||
template <class T, class M>
|
||||
category(std::initializer_list<T>, const M&)->category<T, M>;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace axis
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user