mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 13:14:06 +00:00
getting rid of buffer.hpp again, better operator+= for dynamic_storage, no move from static_storage
This commit is contained in:
parent
65a32b3630
commit
5f23c006a4
@ -1,250 +0,0 @@
|
||||
// Copyright 2015-2016 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_BUFFER_HPP_
|
||||
#define _BOOST_HISTOGRAM_DETAIL_BUFFER_HPP_
|
||||
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <new> // for bad_alloc exception
|
||||
#include <boost/mpl/map.hpp>
|
||||
#include <boost/mpl/pair.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/histogram/detail/weight.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
|
||||
using type_to_int = mpl::map<
|
||||
mpl::pair<int8_t, mpl::int_<1>>,
|
||||
mpl::pair<int16_t, mpl::int_<2>>,
|
||||
mpl::pair<int32_t, mpl::int_<3>>,
|
||||
mpl::pair<int64_t, mpl::int_<4>>,
|
||||
mpl::pair<uint8_t, mpl::int_<1>>,
|
||||
mpl::pair<uint16_t, mpl::int_<2>>,
|
||||
mpl::pair<uint32_t, mpl::int_<3>>,
|
||||
mpl::pair<uint64_t, mpl::int_<4>>,
|
||||
mpl::pair<weight_t, mpl::int_<6>>
|
||||
>;
|
||||
|
||||
using int_to_type = mpl::map<
|
||||
mpl::pair<mpl::int_<1>, uint8_t>,
|
||||
mpl::pair<mpl::int_<2>, uint16_t>,
|
||||
mpl::pair<mpl::int_<3>, uint32_t>,
|
||||
mpl::pair<mpl::int_<4>, uint64_t>,
|
||||
mpl::pair<mpl::int_<6>, weight_t>
|
||||
>;
|
||||
|
||||
template <typename T>
|
||||
using next_storage_type =
|
||||
typename mpl::at<int_to_type,
|
||||
typename mpl::next<
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type
|
||||
>::type;
|
||||
|
||||
class buffer {
|
||||
public:
|
||||
|
||||
explicit
|
||||
buffer(std::size_t s = 0) :
|
||||
type_(),
|
||||
size_(s),
|
||||
ptr_(nullptr)
|
||||
{}
|
||||
|
||||
buffer(const buffer& o) :
|
||||
type_(o.type_), size_(o.size_), ptr_(nullptr)
|
||||
{
|
||||
realloc(depth());
|
||||
std::copy(static_cast<const char*>(o.ptr_),
|
||||
static_cast<const char*>(o.ptr_) + size() * depth(),
|
||||
static_cast<char*>(ptr_));
|
||||
}
|
||||
|
||||
buffer& operator=(const buffer& o)
|
||||
{
|
||||
if (this != &o) {
|
||||
if (size_ != o.size_ || type_ != o.type_) {
|
||||
size_ = o.size_;
|
||||
type_ = o.type_;
|
||||
realloc(depth());
|
||||
}
|
||||
std::copy(static_cast<const char*>(o.ptr_),
|
||||
static_cast<const char*>(o.ptr_) + size() * depth(),
|
||||
static_cast<char*>(ptr_));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
buffer(buffer&& o) :
|
||||
type_(o.type_),
|
||||
size_(o.size_),
|
||||
ptr_(o.ptr_)
|
||||
{
|
||||
o.size_ = 0;
|
||||
o.type_ = type();
|
||||
o.ptr_ = nullptr;
|
||||
}
|
||||
|
||||
buffer& operator=(buffer&& o)
|
||||
{
|
||||
if (this != &o) {
|
||||
std::free(ptr_);
|
||||
type_ = o.type_;
|
||||
size_ = o.size_;
|
||||
ptr_ = o.ptr_;
|
||||
o.type_ = type();
|
||||
o.size_ = 0;
|
||||
o.ptr_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, template<typename> class Storage>
|
||||
buffer(const Storage<T>& o) :
|
||||
size_(o.size()),
|
||||
ptr_(nullptr)
|
||||
{
|
||||
using U = typename mpl::at<
|
||||
int_to_type,
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type;
|
||||
realloc(sizeof(U));
|
||||
std::copy(o.data_, o.data_ + size_, &at<U>(0));
|
||||
type_.set<U>();
|
||||
}
|
||||
|
||||
template <typename T, template<typename> class Storage>
|
||||
buffer& operator=(const Storage<T>& o) {
|
||||
size_ = o.size();
|
||||
using U = typename mpl::at<
|
||||
int_to_type,
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type;
|
||||
realloc(sizeof(U));
|
||||
std::copy(o.data_, o.data_ + size_, &at<T>(0));
|
||||
type_.set<U>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, template<typename> class Storage>
|
||||
buffer(Storage<T>&& o) :
|
||||
size_(o.size_),
|
||||
ptr_(const_cast<void*>(o.data_))
|
||||
{
|
||||
using U = typename mpl::at<
|
||||
int_to_type,
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type;
|
||||
type_.set<U>();
|
||||
o.size_ = 0;
|
||||
o.data_ = nullptr;
|
||||
}
|
||||
|
||||
template <typename T, template<typename> class Storage>
|
||||
buffer& operator=(Storage<T>&& o)
|
||||
{
|
||||
using U = typename mpl::at<
|
||||
int_to_type,
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type;
|
||||
std::free(ptr_);
|
||||
size_ = o.size_;
|
||||
ptr_ = static_cast<void*>(o.data_);
|
||||
type_.set<U>();
|
||||
o.size_ = 0;
|
||||
o.data_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~buffer() { std::free(ptr_); }
|
||||
|
||||
std::size_t size() const { return size_; }
|
||||
unsigned id() const { return type_.id_; }
|
||||
unsigned depth() const { return type_.depth_; }
|
||||
const void* data() const { return ptr_; }
|
||||
|
||||
bool operator==(const buffer& o) const {
|
||||
return size_ == o.size_ &&
|
||||
type_.id_ == o.type_.id_ &&
|
||||
std::equal(static_cast<char*>(ptr_),
|
||||
static_cast<char*>(ptr_) + size_ * depth(),
|
||||
static_cast<char*>(o.ptr_));
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename U = next_storage_type<T>>
|
||||
void grow() {
|
||||
static_assert(sizeof(U) >= sizeof(T), "U must be as large or larger than T");
|
||||
realloc(sizeof(U));
|
||||
std::copy_backward(&at<T>(0), &at<T>(size_), &at<U>(size_));
|
||||
type_.set<U>();
|
||||
}
|
||||
|
||||
void wconvert()
|
||||
{
|
||||
switch (type_.id_) {
|
||||
case 0: initialize<weight_t>(); break;
|
||||
case 1: grow<uint8_t, weight_t> (); break;
|
||||
case 2: grow<uint16_t, weight_t>(); break;
|
||||
case 3: grow<uint32_t, weight_t>(); break;
|
||||
case 4: grow<uint64_t, weight_t>(); break;
|
||||
case 6: /* do nothing */ break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void initialize() {
|
||||
type_.set<T>();
|
||||
ptr_ = nullptr;
|
||||
realloc(sizeof(T));
|
||||
std::fill(&at<T>(0), &at<T>(size_), T(0));
|
||||
}
|
||||
|
||||
void realloc(unsigned d)
|
||||
{
|
||||
ptr_ = std::realloc(ptr_, size_ * d);
|
||||
if (!ptr_ && (size_ * d > 0))
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& at(std::size_t i) { return static_cast<T*>(ptr_)[i]; }
|
||||
|
||||
template <typename T>
|
||||
const T& at(std::size_t i) const { return static_cast<const T*>(ptr_)[i]; }
|
||||
|
||||
private:
|
||||
struct type {
|
||||
char id_, depth_;
|
||||
type() : id_(0), depth_(0) {}
|
||||
type(const type&) = default;
|
||||
type& operator=(const type&) = default;
|
||||
template <typename T>
|
||||
void set() {
|
||||
id_ = mpl::at<type_to_int, T>::type::value;
|
||||
depth_ = sizeof(T);
|
||||
}
|
||||
bool operator==(const type& o) const { return id_ == o.id_; }
|
||||
bool operator!=(const type& o) const { return id_ != o.id_; }
|
||||
};
|
||||
|
||||
type type_;
|
||||
std::size_t size_;
|
||||
void* ptr_;
|
||||
|
||||
template <class Archive>
|
||||
friend void serialize(Archive&, buffer&, unsigned);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -7,30 +7,35 @@
|
||||
#ifndef _BOOST_HISTOGRAM_DETAIL_WEIGHT_HPP_
|
||||
#define _BOOST_HISTOGRAM_DETAIL_WEIGHT_HPP_
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
namespace detail {
|
||||
|
||||
/// Used by nstore to hold a sum of weighted counts and a variance estimate
|
||||
struct weight_t {
|
||||
struct weight_t
|
||||
: boost::operators<weight_t>
|
||||
{
|
||||
double w, w2;
|
||||
weight_t() = default;
|
||||
weight_t(const weight_t&) = default;
|
||||
weight_t(weight_t&&) = default;
|
||||
weight_t& operator=(const weight_t&) = default;
|
||||
weight_t& operator=(weight_t&&) = default;
|
||||
|
||||
weight_t& operator+=(const weight_t& o)
|
||||
{ w += o.w; w2 += o.w2; return *this; }
|
||||
weight_t& operator++()
|
||||
{ ++w; ++w2; return *this; }
|
||||
bool operator==(const weight_t& o) const
|
||||
{ return w == o.w && w2 == o.w2; }
|
||||
bool operator!=(const weight_t& o) const
|
||||
{ return !operator==(o); }
|
||||
|
||||
weight_t& add_weight(double v)
|
||||
{ w += v; w2 += v*v; return *this; }
|
||||
|
||||
explicit weight_t(int v) : w(v), w2(v) {}
|
||||
template <typename T>
|
||||
explicit weight_t(const T& t) : w(static_cast<double>(t)), w2(w) {}
|
||||
|
||||
template <typename T>
|
||||
weight_t& operator=(T v)
|
||||
|
@ -8,11 +8,17 @@
|
||||
#define _BOOST_HISTOGRAM_DYNAMIC_STORAGE_HPP_
|
||||
|
||||
#include <boost/histogram/detail/weight.hpp>
|
||||
#include <boost/histogram/detail/buffer.hpp>
|
||||
#include <boost/histogram/detail/mpl.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/map.hpp>
|
||||
#include <boost/mpl/pair.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <cstdlib> // malloc/free
|
||||
#include <new> // for bad_alloc exception
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
@ -20,56 +26,253 @@
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
namespace {
|
||||
namespace detail {
|
||||
|
||||
static_assert(std::is_pod<detail::weight_t>::value, "weight_t must be POD");
|
||||
static_assert(std::is_pod<weight_t>::value, "weight_t must be POD");
|
||||
|
||||
using type_to_int = mpl::map<
|
||||
mpl::pair<weight_t, mpl::int_<-1>>,
|
||||
|
||||
mpl::pair<int8_t, mpl::int_<1>>,
|
||||
mpl::pair<int16_t, mpl::int_<2>>,
|
||||
mpl::pair<int32_t, mpl::int_<3>>,
|
||||
mpl::pair<int64_t, mpl::int_<4>>,
|
||||
|
||||
mpl::pair<uint8_t, mpl::int_<1>>,
|
||||
mpl::pair<uint16_t, mpl::int_<2>>,
|
||||
mpl::pair<uint32_t, mpl::int_<3>>,
|
||||
mpl::pair<uint64_t, mpl::int_<4>>
|
||||
>;
|
||||
|
||||
using int_to_type = mpl::map<
|
||||
mpl::pair<mpl::int_<-1>, weight_t>,
|
||||
mpl::pair<mpl::int_<1>, uint8_t>,
|
||||
mpl::pair<mpl::int_<2>, uint16_t>,
|
||||
mpl::pair<mpl::int_<3>, uint32_t>,
|
||||
mpl::pair<mpl::int_<4>, uint64_t>
|
||||
>;
|
||||
|
||||
template <typename T>
|
||||
void increase_impl(detail::buffer& buf, std::size_t i) {
|
||||
auto& b = buf.at<T>(i);
|
||||
if (b < std::numeric_limits<T>::max())
|
||||
++b;
|
||||
using storage_type =
|
||||
typename mpl::at<
|
||||
detail::int_to_type,
|
||||
typename mpl::at<
|
||||
detail::type_to_int, T
|
||||
>::type
|
||||
>::type;
|
||||
|
||||
template <typename T>
|
||||
using next_storage_type =
|
||||
typename mpl::at<int_to_type,
|
||||
typename mpl::next<
|
||||
typename mpl::at<type_to_int, T>::type
|
||||
>::type
|
||||
>::type;
|
||||
|
||||
struct buffer
|
||||
{
|
||||
explicit buffer(std::size_t s = 0) :
|
||||
size_(s),
|
||||
ptr_(nullptr)
|
||||
{}
|
||||
|
||||
buffer(const buffer& o) :
|
||||
type_(o.type_), size_(o.size_), ptr_(nullptr)
|
||||
{
|
||||
realloc(type_.depth_);
|
||||
std::copy(static_cast<const char*>(o.ptr_),
|
||||
static_cast<const char*>(o.ptr_) + size_ * type_.depth_,
|
||||
static_cast<char*>(ptr_));
|
||||
}
|
||||
|
||||
buffer& operator=(const buffer& o)
|
||||
{
|
||||
if (this != &o) {
|
||||
if (size_ != o.size_ || type_.id_ != o.type_.id_) {
|
||||
size_ = o.size_;
|
||||
type_ = o.type_;
|
||||
realloc(type_.depth_);
|
||||
}
|
||||
std::copy(static_cast<const char*>(o.ptr_),
|
||||
static_cast<const char*>(o.ptr_) + size_ * type_.depth_,
|
||||
static_cast<char*>(ptr_));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
buffer(buffer&& o) :
|
||||
type_(o.type_),
|
||||
size_(o.size_),
|
||||
ptr_(o.ptr_)
|
||||
{
|
||||
o.size_ = 0;
|
||||
o.type_ = type();
|
||||
o.ptr_ = nullptr;
|
||||
}
|
||||
|
||||
buffer& operator=(buffer&& o)
|
||||
{
|
||||
if (this != &o) {
|
||||
destroy_any();
|
||||
type_ = o.type_;
|
||||
size_ = o.size_;
|
||||
ptr_ = o.ptr_;
|
||||
o.type_ = type();
|
||||
o.size_ = 0;
|
||||
o.ptr_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~buffer() { destroy_any(); }
|
||||
|
||||
template <typename T>
|
||||
void create() {
|
||||
type_.set<T>();
|
||||
ptr_ = std::malloc(size_ * sizeof(T));
|
||||
new (ptr_) T[size_];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void destroy() {
|
||||
std::free(ptr_);
|
||||
ptr_ = nullptr;
|
||||
}
|
||||
|
||||
void destroy_any() {
|
||||
switch (type_.id_) {
|
||||
case -1: destroy<weight_t>(); break;
|
||||
case 0: /* do nothing */ break;
|
||||
case 1: destroy<uint8_t>(); break;
|
||||
case 2: destroy<uint16_t>(); break;
|
||||
case 3: destroy<uint32_t>(); break;
|
||||
case 4: destroy<uint64_t>(); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename U = next_storage_type<T>>
|
||||
void grow() {
|
||||
static_assert(sizeof(U) >= sizeof(T), "U must be as large or larger than T");
|
||||
realloc(sizeof(U));
|
||||
std::copy_backward(&at<T>(0), &at<T>(size_), &at<U>(size_));
|
||||
type_.set<U>();
|
||||
}
|
||||
|
||||
void wconvert()
|
||||
{
|
||||
switch (type_.id_) {
|
||||
case -1: /* do nothing */ break;
|
||||
case 0: initialize<weight_t>(); break;
|
||||
case 1: grow<uint8_t, weight_t> (); break;
|
||||
case 2: grow<uint16_t, weight_t>(); break;
|
||||
case 3: grow<uint32_t, weight_t>(); break;
|
||||
case 4: grow<uint64_t, weight_t>(); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void initialize() {
|
||||
type_.set<T>();
|
||||
ptr_ = nullptr;
|
||||
realloc(sizeof(T));
|
||||
std::fill(&at<T>(0), &at<T>(size_), T(0));
|
||||
}
|
||||
|
||||
void realloc(unsigned d)
|
||||
{
|
||||
ptr_ = std::realloc(ptr_, size_ * d);
|
||||
if (!ptr_ && (size_ * d > 0))
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& at(std::size_t i) { return static_cast<T*>(ptr_)[i]; }
|
||||
|
||||
template <typename T>
|
||||
const T& at(std::size_t i) const { return static_cast<const T*>(ptr_)[i]; }
|
||||
|
||||
struct type {
|
||||
char id_ = 0, depth_ = 0;
|
||||
template <typename T>
|
||||
void set() {
|
||||
id_ = mpl::at<type_to_int, T>::type::value;
|
||||
depth_ = sizeof(T);
|
||||
}
|
||||
} type_;
|
||||
std::size_t size_;
|
||||
void* ptr_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void increase_impl(buffer& b, std::size_t i) {
|
||||
auto& bi = b.at<T>(i);
|
||||
if (bi < std::numeric_limits<T>::max())
|
||||
++bi;
|
||||
else {
|
||||
buf.grow<T>();
|
||||
b.grow<T>();
|
||||
using U = detail::next_storage_type<T>;
|
||||
auto& b = buf.at<U>(i);
|
||||
++b;
|
||||
++b.at<U>(i);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void increase_impl<uint64_t>(detail::buffer& buf, std::size_t i) {
|
||||
auto& b = buf.at<uint64_t>(i);
|
||||
if (b < std::numeric_limits<uint64_t>::max())
|
||||
++b;
|
||||
void increase_impl<uint64_t>(buffer& b, std::size_t i) {
|
||||
auto& bi = b.at<uint64_t>(i);
|
||||
if (bi < std::numeric_limits<uint64_t>::max())
|
||||
++bi;
|
||||
else
|
||||
throw std::overflow_error("histogram overflow");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void add_impl(detail::buffer& buf, std::size_t i, uint64_t o) {
|
||||
auto& b = buf.at<T>(i);
|
||||
if (static_cast<T>(std::numeric_limits<T>::max() - b) >= o)
|
||||
b += o;
|
||||
else {
|
||||
buf.grow<T>();
|
||||
add_impl<detail::next_storage_type<T>>(buf, i, o);
|
||||
template <typename T, typename TO>
|
||||
struct add_one_impl {
|
||||
static void apply(buffer& b, std::size_t i, const TO& o) {
|
||||
auto& bi = b.at<T>(i);
|
||||
if (static_cast<T>(std::numeric_limits<T>::max() - bi) >= o)
|
||||
bi += o;
|
||||
else {
|
||||
b.grow<T>();
|
||||
add_one_impl<detail::next_storage_type<T>, TO>::apply(b, i, o);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TO>
|
||||
struct add_one_impl<uint64_t, TO> {
|
||||
static void apply(buffer& b, std::size_t i, const TO& o) {
|
||||
auto& bi = b.at<uint64_t>(i);
|
||||
if (static_cast<uint64_t>(std::numeric_limits<uint64_t>::max() - bi) >= o)
|
||||
bi += o;
|
||||
else
|
||||
throw std::overflow_error("histogram overflow");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TO>
|
||||
void add_impl(buffer& b, const buffer& o) {
|
||||
for (decltype(b.size_) i = 0; i < b.size_; ++i)
|
||||
switch (b.type_.id_) {
|
||||
case -1: b.at<weight_t>(i) += o.at<TO>(i); break;
|
||||
case 0: b.initialize<uint8_t>(); // fall through
|
||||
case 1: add_one_impl<uint8_t, TO>::apply(b, i, o.at<TO>(i)); break;
|
||||
case 2: add_one_impl<uint16_t, TO>::apply(b, i, o.at<TO>(i)); break;
|
||||
case 3: add_one_impl<uint32_t, TO>::apply(b, i, o.at<TO>(i)); break;
|
||||
case 4: add_one_impl<uint64_t, TO>::apply(b, i, o.at<TO>(i)); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void add_impl<uint64_t>(detail::buffer& buf, std::size_t i, uint64_t o) {
|
||||
auto& b = buf.at<uint64_t>(i);
|
||||
if (static_cast<uint64_t>(std::numeric_limits<uint64_t>::max() - b) >= o)
|
||||
b += o;
|
||||
else
|
||||
throw std::overflow_error("histogram overflow");
|
||||
void add_impl<weight_t>(buffer& b, const buffer& o) {
|
||||
b.wconvert();
|
||||
for (decltype(b.size_) i = 0; i < b.size_; ++i)
|
||||
b.at<weight_t>(i) += o.at<weight_t>(i);
|
||||
}
|
||||
}
|
||||
|
||||
class dynamic_storage {
|
||||
using weight_t = detail::weight_t;
|
||||
} // NS detail
|
||||
|
||||
class dynamic_storage
|
||||
{
|
||||
public:
|
||||
using value_t = double;
|
||||
using variance_t = double;
|
||||
@ -81,45 +284,37 @@ public:
|
||||
|
||||
dynamic_storage() = default;
|
||||
dynamic_storage(const dynamic_storage&) = default;
|
||||
dynamic_storage(dynamic_storage&&) = default;
|
||||
dynamic_storage& operator=(const dynamic_storage&) = default;
|
||||
dynamic_storage(dynamic_storage&&) = default;
|
||||
dynamic_storage& operator=(dynamic_storage&&) = default;
|
||||
|
||||
template <typename T,
|
||||
template <typename> class Storage,
|
||||
typename = detail::is_standard_integral<T>>
|
||||
dynamic_storage(const Storage<T>& o) :
|
||||
buffer_(o)
|
||||
{}
|
||||
buffer_(o.size())
|
||||
{
|
||||
using U = detail::storage_type<T>;
|
||||
buffer_.create<U>();
|
||||
std::copy(o.data(), o.data() + buffer_.size_, &buffer_.at<U>(0));
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
template <typename> class Storage,
|
||||
typename = detail::is_standard_integral<T>>
|
||||
dynamic_storage& operator=(const Storage<T>& o)
|
||||
{
|
||||
buffer_ = o;
|
||||
buffer_.destroy_any();
|
||||
buffer_.size_ = o.size();
|
||||
using U = detail::storage_type<T>;
|
||||
buffer_.create<U>();
|
||||
std::copy(o.data(), o.data() + buffer_.size_, &buffer_.at<U>(0));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
template <typename> class Storage,
|
||||
typename = detail::is_standard_integral<T>>
|
||||
dynamic_storage(Storage<T>&& o) :
|
||||
buffer_(std::move(o))
|
||||
{}
|
||||
|
||||
template <typename T,
|
||||
template <typename> class Storage,
|
||||
typename = detail::is_standard_integral<T>>
|
||||
dynamic_storage& operator=(Storage<T>&& o)
|
||||
{
|
||||
buffer_ = std::move(o);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t size() const { return buffer_.size(); }
|
||||
unsigned depth() const { return buffer_.depth(); }
|
||||
const void* data() const { return buffer_.data(); }
|
||||
std::size_t size() const { return buffer_.size_; }
|
||||
unsigned depth() const { return buffer_.type_.depth_; }
|
||||
const void* data() const { return buffer_.ptr_; }
|
||||
void increase(std::size_t i);
|
||||
void increase(std::size_t i, double w);
|
||||
value_t value(std::size_t i) const;
|
||||
@ -136,13 +331,13 @@ private:
|
||||
inline
|
||||
void dynamic_storage::increase(std::size_t i)
|
||||
{
|
||||
switch (buffer_.id()) {
|
||||
switch (buffer_.type_.id_) {
|
||||
case -1: ++(buffer_.at<detail::weight_t>(i)); break;
|
||||
case 0: buffer_.initialize<uint8_t>(); // and fall through
|
||||
case 1: increase_impl<uint8_t> (buffer_, i); break;
|
||||
case 2: increase_impl<uint16_t>(buffer_, i); break;
|
||||
case 3: increase_impl<uint32_t>(buffer_, i); break;
|
||||
case 4: increase_impl<uint64_t>(buffer_, i); break;
|
||||
case 6: ++(buffer_.at<weight_t>(i)); break;
|
||||
case 1: detail::increase_impl<uint8_t> (buffer_, i); break;
|
||||
case 2: detail::increase_impl<uint16_t>(buffer_, i); break;
|
||||
case 3: detail::increase_impl<uint32_t>(buffer_, i); break;
|
||||
case 4: detail::increase_impl<uint64_t>(buffer_, i); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,39 +345,19 @@ inline
|
||||
void dynamic_storage::increase(std::size_t i, double w)
|
||||
{
|
||||
buffer_.wconvert();
|
||||
buffer_.at<weight_t>(i).add_weight(w);
|
||||
buffer_.at<detail::weight_t>(i).add_weight(w);
|
||||
}
|
||||
|
||||
inline
|
||||
dynamic_storage& dynamic_storage::operator+=(const dynamic_storage& o)
|
||||
{
|
||||
if (o.depth()) {
|
||||
if (o.buffer_.id() == 6) {
|
||||
buffer_.wconvert();
|
||||
for (std::size_t i = 0; i < size(); ++i)
|
||||
buffer_.at<weight_t>(i) += o.buffer_.at<weight_t>(i);
|
||||
}
|
||||
else {
|
||||
auto i = size();
|
||||
while (i--) {
|
||||
uint64_t n = 0;
|
||||
switch (o.buffer_.id()) {
|
||||
/* case 0 is already excluded by the initial if statement */
|
||||
case 1: n = o.buffer_.at<uint8_t> (i); break;
|
||||
case 2: n = o.buffer_.at<uint16_t>(i); break;
|
||||
case 3: n = o.buffer_.at<uint32_t>(i); break;
|
||||
case 4: n = o.buffer_.at<uint64_t>(i); break;
|
||||
}
|
||||
switch (buffer_.id()) {
|
||||
case 0: buffer_.initialize<uint8_t>(); // and fall through
|
||||
case 1: add_impl<uint8_t> (buffer_, i, n); break;
|
||||
case 2: add_impl<uint16_t>(buffer_, i, n); break;
|
||||
case 3: add_impl<uint32_t>(buffer_, i, n); break;
|
||||
case 4: add_impl<uint64_t>(buffer_, i, n); break;
|
||||
case 6: buffer_.at<weight_t>(i) += n; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (o.buffer_.type_.id_) {
|
||||
case -1: detail::add_impl<detail::weight_t>(buffer_, o.buffer_); break;
|
||||
case 0: /* do nothing */ break;
|
||||
case 1: detail::add_impl<uint8_t>(buffer_, o.buffer_); break;
|
||||
case 2: detail::add_impl<uint16_t>(buffer_, o.buffer_); break;
|
||||
case 3: detail::add_impl<uint32_t>(buffer_, o.buffer_); break;
|
||||
case 4: detail::add_impl<uint64_t>(buffer_, o.buffer_); break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -190,13 +365,13 @@ dynamic_storage& dynamic_storage::operator+=(const dynamic_storage& o)
|
||||
inline
|
||||
dynamic_storage::value_t dynamic_storage::value(std::size_t i) const
|
||||
{
|
||||
switch (buffer_.id()) {
|
||||
case 0: break;
|
||||
switch (buffer_.type_.id_) {
|
||||
case -1: return buffer_.at<detail::weight_t>(i).w;
|
||||
case 0: /* do nothing */ break;
|
||||
case 1: return buffer_.at<uint8_t> (i);
|
||||
case 2: return buffer_.at<uint16_t>(i);
|
||||
case 3: return buffer_.at<uint32_t>(i);
|
||||
case 4: return buffer_.at<uint64_t>(i);
|
||||
case 6: return buffer_.at<weight_t>(i).w;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
@ -204,13 +379,13 @@ dynamic_storage::value_t dynamic_storage::value(std::size_t i) const
|
||||
inline
|
||||
dynamic_storage::variance_t dynamic_storage::variance(std::size_t i) const
|
||||
{
|
||||
switch (buffer_.id()) {
|
||||
case 0: break;
|
||||
switch (buffer_.type_.id_) {
|
||||
case -1: return buffer_.at<detail::weight_t>(i).w2;
|
||||
case 0: /* do nothing */ break;
|
||||
case 1: return buffer_.at<uint8_t> (i);
|
||||
case 2: return buffer_.at<uint16_t>(i);
|
||||
case 3: return buffer_.at<uint32_t>(i);
|
||||
case 4: return buffer_.at<uint64_t>(i);
|
||||
case 6: return buffer_.at<weight_t>(i).w2;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <boost/histogram/dynamic_storage.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
#include <boost/histogram/detail/weight.hpp>
|
||||
#include <boost/histogram/detail/buffer.hpp>
|
||||
#include <boost/histogram/detail/tiny_string.hpp>
|
||||
#include <boost/serialization/variant.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
@ -38,32 +37,6 @@ inline void serialize(Archive& ar, weight_t& wt, unsigned version)
|
||||
ar & wt.w2;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
inline void serialize(Archive& ar, buffer& buf, unsigned version)
|
||||
{
|
||||
ar & buf.size_;
|
||||
ar & buf.type_.id_;
|
||||
ar & buf.type_.depth_;
|
||||
if (Archive::is_loading::value) {
|
||||
buf.realloc(buf.depth());
|
||||
// switch (buf.type_) {
|
||||
// case 1: buf.create<uint8_t>(); break;
|
||||
// case 2: buf.create<uint16_t>(); break;
|
||||
// case 3: buf.create<uint32_t>(); break;
|
||||
// case 4: buf.create<uint64_t>(); break;
|
||||
// case 6: buf.create<weight_t>(); break;
|
||||
// }
|
||||
}
|
||||
switch (buf.type_.id_) {
|
||||
case 0: buf.ptr_ = nullptr; break;
|
||||
case 1: ar & serialization::make_array(&buf.at<uint8_t>(0), buf.size_); break;
|
||||
case 2: ar & serialization::make_array(&buf.at<uint16_t>(0), buf.size_); break;
|
||||
case 3: ar & serialization::make_array(&buf.at<uint32_t>(0), buf.size_); break;
|
||||
case 4: ar & serialization::make_array(&buf.at<uint64_t>(0), buf.size_); break;
|
||||
case 6: ar & serialization::make_array(&buf.at<weight_t>(0), buf.size_); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive& ar, tiny_string& s, unsigned version)
|
||||
{
|
||||
@ -91,7 +64,30 @@ inline void serialize(Archive& ar, static_storage<T> & store, unsigned version)
|
||||
template <class Archive>
|
||||
inline void serialize(Archive& ar, dynamic_storage & store, unsigned version)
|
||||
{
|
||||
ar & store.buffer_;
|
||||
auto& b = store.buffer_;
|
||||
if (Archive::is_loading::value)
|
||||
b.destroy_any();
|
||||
ar & b.size_;
|
||||
ar & b.type_.id_;
|
||||
ar & b.type_.depth_;
|
||||
if (Archive::is_loading::value) {
|
||||
switch (b.type_.id_) {
|
||||
case -1: b.create<detail::weight_t>(); break;
|
||||
case 0: b.ptr_ = nullptr; break;
|
||||
case 1: b.create<uint8_t>(); break;
|
||||
case 2: b.create<uint16_t>(); break;
|
||||
case 3: b.create<uint32_t>(); break;
|
||||
case 4: b.create<uint64_t>(); break;
|
||||
}
|
||||
}
|
||||
switch (b.type_.id_) {
|
||||
case -1: ar & serialization::make_array(&b.at<detail::weight_t>(0), b.size_); break;
|
||||
case 0: /* nothing to do */ break;
|
||||
case 1: ar & serialization::make_array(&b.at<uint8_t>(0), b.size_); break;
|
||||
case 2: ar & serialization::make_array(&b.at<uint16_t>(0), b.size_); break;
|
||||
case 3: ar & serialization::make_array(&b.at<uint32_t>(0), b.size_); break;
|
||||
case 4: ar & serialization::make_array(&b.at<uint64_t>(0), b.size_); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
|
@ -12,8 +12,6 @@
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
namespace detail { class buffer; }
|
||||
|
||||
template <typename T>
|
||||
class static_storage {
|
||||
public:
|
||||
@ -104,7 +102,7 @@ namespace histogram {
|
||||
|
||||
std::size_t size() const { return size_; }
|
||||
constexpr unsigned depth() const { return sizeof(T); }
|
||||
const void* data() const { return static_cast<const void*>(data_); }
|
||||
const T* data() const { return data_; }
|
||||
void increase(std::size_t i) { ++(data_[i]); }
|
||||
value_t value(std::size_t i) const { return data_[i]; }
|
||||
variance_t variance(std::size_t i) const { return data_[i]; }
|
||||
@ -128,8 +126,6 @@ namespace histogram {
|
||||
data_ = new T[size_];
|
||||
}
|
||||
|
||||
friend detail::buffer;
|
||||
|
||||
template <typename Archive, typename U>
|
||||
friend void serialize(Archive&, static_storage<U>&, unsigned);
|
||||
};
|
||||
|
@ -8,11 +8,40 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
#include <boost/histogram/detail/buffer.hpp>
|
||||
#include <boost/histogram/detail/weight.hpp>
|
||||
#include <boost/histogram/detail/tiny_string.hpp>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
using namespace boost::histogram::detail;
|
||||
|
||||
// bool operator==(const buffer& a, const buffer& b)
|
||||
// {
|
||||
// if (!(a.size() == b.size() &&
|
||||
// a.id() == b.id() &&
|
||||
// a.depth() == b.depth()))
|
||||
// return false;
|
||||
// switch (a.id()) {
|
||||
// case -1: return std::equal(&a.at<weight_t>(0),
|
||||
// &a.at<weight_t>(a.size()),
|
||||
// &b.at<weight_t>(0));
|
||||
// case 0: return true;
|
||||
// case 1: return std::equal(&a.at<uint8_t>(0),
|
||||
// &a.at<uint8_t>(a.size()),
|
||||
// &b.at<uint8_t>(0));
|
||||
// case 2: return std::equal(&a.at<uint16_t>(0),
|
||||
// &a.at<uint16_t>(a.size()),
|
||||
// &b.at<uint16_t>(0));
|
||||
// case 3: return std::equal(&a.at<uint32_t>(0),
|
||||
// &a.at<uint32_t>(a.size()),
|
||||
// &b.at<uint32_t>(0));
|
||||
// case 4: return std::equal(&a.at<uint64_t>(0),
|
||||
// &a.at<uint64_t>(a.size()),
|
||||
// &b.at<uint64_t>(0));
|
||||
// }
|
||||
// BOOST_ASSERT(!"never reach this");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(escape_0)
|
||||
{
|
||||
std::ostringstream os;
|
||||
@ -34,99 +63,99 @@ BOOST_AUTO_TEST_CASE(escape_2)
|
||||
BOOST_CHECK_EQUAL(os.str(), std::string("'\\\'abc\\\''"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_ctor_and_get)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
BOOST_CHECK_EQUAL(a.depth(), 1);
|
||||
a.at<uint8_t>(0) = 0;
|
||||
a.at<uint8_t>(1) = 1;
|
||||
a.at<uint8_t>(2) = 0;
|
||||
BOOST_CHECK_EQUAL(a.at<uint8_t>(0), 0);
|
||||
BOOST_CHECK_EQUAL(a.at<uint8_t>(1), 1);
|
||||
BOOST_CHECK_EQUAL(a.at<uint8_t>(2), 0);
|
||||
BOOST_CHECK(a == a);
|
||||
auto b = buffer(3);
|
||||
b.initialize<uint8_t>();
|
||||
BOOST_CHECK(!(a == b));
|
||||
auto c = buffer(1);
|
||||
c.initialize<uint8_t>();
|
||||
BOOST_CHECK(!(a == c));
|
||||
auto d = buffer();
|
||||
BOOST_CHECK(!(a == d));
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_ctor_and_get)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
// BOOST_CHECK_EQUAL(a.depth(), 1);
|
||||
// a.at<uint8_t>(0) = 0;
|
||||
// a.at<uint8_t>(1) = 1;
|
||||
// a.at<uint8_t>(2) = 0;
|
||||
// BOOST_CHECK_EQUAL(a.at<uint8_t>(0), 0);
|
||||
// BOOST_CHECK_EQUAL(a.at<uint8_t>(1), 1);
|
||||
// BOOST_CHECK_EQUAL(a.at<uint8_t>(2), 0);
|
||||
// BOOST_CHECK(a == a);
|
||||
// auto b = buffer(3);
|
||||
// b.initialize<uint8_t>();
|
||||
// BOOST_CHECK(!(a == b));
|
||||
// auto c = buffer(1);
|
||||
// c.initialize<uint8_t>();
|
||||
// BOOST_CHECK(!(a == c));
|
||||
// auto d = buffer();
|
||||
// BOOST_CHECK(!(a == d));
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_copy_ctor)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
a.at<uint8_t>(1) = 1;
|
||||
auto b = a;
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
BOOST_CHECK(a == b);
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_copy_ctor)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// a.at<uint8_t>(1) = 1;
|
||||
// auto b = a;
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
// BOOST_CHECK(a == b);
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_move_ctor)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
a.at<uint8_t>(1) = 1;
|
||||
auto b = std::move(a);
|
||||
BOOST_CHECK_EQUAL(a.size(), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
BOOST_CHECK(!(a == b));
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_move_ctor)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// a.at<uint8_t>(1) = 1;
|
||||
// auto b = std::move(a);
|
||||
// BOOST_CHECK_EQUAL(a.size(), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
// BOOST_CHECK(!(a == b));
|
||||
// }
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_copy_assign)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
a.at<uint8_t>(1) = 1;
|
||||
auto b = buffer(3);
|
||||
b.initialize<uint8_t>();
|
||||
b = a;
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
BOOST_CHECK(a == b);
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_copy_assign)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// a.at<uint8_t>(1) = 1;
|
||||
// auto b = buffer(3);
|
||||
// b.initialize<uint8_t>();
|
||||
// b = a;
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
// BOOST_CHECK(a == b);
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_move_assign)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
a.at<uint8_t>(1) = 1;
|
||||
auto b = buffer(3);
|
||||
b.initialize<uint8_t>();
|
||||
b = std::move(a);
|
||||
BOOST_CHECK_EQUAL(a.size(), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
BOOST_CHECK(!(a == b));
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_move_assign)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// a.at<uint8_t>(1) = 1;
|
||||
// auto b = buffer(3);
|
||||
// b.initialize<uint8_t>();
|
||||
// b = std::move(a);
|
||||
// BOOST_CHECK_EQUAL(a.size(), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(0), 0);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(1), 1);
|
||||
// BOOST_CHECK_EQUAL(b.at<uint8_t>(2), 0);
|
||||
// BOOST_CHECK(!(a == b));
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(buffer_realloc)
|
||||
{
|
||||
auto a = buffer(3);
|
||||
a.initialize<uint8_t>();
|
||||
BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
a.at<uint8_t>(0) = 1;
|
||||
a.at<uint8_t>(1) = 2;
|
||||
a.at<uint8_t>(2) = 3;
|
||||
a.grow<uint8_t>();
|
||||
BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
BOOST_CHECK_EQUAL(a.depth(), 2);
|
||||
BOOST_CHECK_EQUAL(a.at<int16_t>(0), 1);
|
||||
BOOST_CHECK_EQUAL(a.at<int16_t>(1), 2);
|
||||
BOOST_CHECK_EQUAL(a.at<int16_t>(2), 3);
|
||||
}
|
||||
// BOOST_AUTO_TEST_CASE(buffer_realloc)
|
||||
// {
|
||||
// auto a = buffer(3);
|
||||
// a.initialize<uint8_t>();
|
||||
// BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
// a.at<uint8_t>(0) = 1;
|
||||
// a.at<uint8_t>(1) = 2;
|
||||
// a.at<uint8_t>(2) = 3;
|
||||
// a.grow<uint8_t>();
|
||||
// BOOST_CHECK_EQUAL(a.size(), 3);
|
||||
// BOOST_CHECK_EQUAL(a.depth(), 2);
|
||||
// BOOST_CHECK_EQUAL(a.at<int16_t>(0), 1);
|
||||
// BOOST_CHECK_EQUAL(a.at<int16_t>(1), 2);
|
||||
// BOOST_CHECK_EQUAL(a.at<int16_t>(2), 3);
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_CASE(tiny_string_test)
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(dynamic_storage_equality)
|
||||
|
||||
template <typename T>
|
||||
void convert_static_storage_impl() {
|
||||
dynamic_storage a(2), b(2), c(2);
|
||||
dynamic_storage a(2), b(2);
|
||||
static_storage<T> s(2);
|
||||
a.increase(0);
|
||||
b.increase(0, 1.0);
|
||||
@ -136,15 +136,17 @@ void convert_static_storage_impl() {
|
||||
BOOST_CHECK(s == b);
|
||||
a = dynamic_storage(2);
|
||||
b = dynamic_storage(2);
|
||||
BOOST_CHECK(a == b);
|
||||
a += s;
|
||||
b += s;
|
||||
BOOST_CHECK(a == s);
|
||||
BOOST_CHECK(s == a);
|
||||
BOOST_CHECK(b == s);
|
||||
BOOST_CHECK(s == b);
|
||||
dynamic_storage c(s);
|
||||
BOOST_CHECK(c == s);
|
||||
BOOST_CHECK(s == c);
|
||||
dynamic_storage d;
|
||||
d = std::move(s);
|
||||
BOOST_CHECK(a == d);
|
||||
d = std::move(s); // cannot move, uses copy
|
||||
BOOST_CHECK(d == s);
|
||||
BOOST_CHECK(s == d);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(convert_static_storage)
|
||||
|
Loading…
x
Reference in New Issue
Block a user