diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 39642d3a..aa81903a 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -18,6 +18,9 @@ python-extension histogram : python/basic_histogram.cpp python/histogram.cpp python/module.cpp + /boost//serialization + /boost//python + boost_histogram : release shared ; boost-install boost_histogram histogram ; diff --git a/include/boost/histogram/basic_histogram.hpp b/include/boost/histogram/basic_histogram.hpp index 5fc586ab..d4b646f2 100644 --- a/include/boost/histogram/basic_histogram.hpp +++ b/include/boost/histogram/basic_histogram.hpp @@ -101,25 +101,27 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_BASE_CTOR bool operator==(const basic_histogram&) const; - template + template inline - size_type pos(const Array& v) const { + size_type pos(const Iterator& begin, const Iterator & end) const { detail::linearize lin(true); int i = axes_.size(); - while (i--) { - lin.x = v[i]; + Iterator itr = end; + while (i-- && (itr-- != begin)) { + lin.x = *itr; apply_visitor(lin, axes_[i]); } return lin.k; } - template + template inline - size_type linearize(const Range &r) const { + size_type linearize(const Iterator &begin, const Iterator & end) const { detail::linearize lin(false); int i = axes_.size(); - while (i--) { - lin.j = r[i]; + Iterator itr = end; + while (i-- && (itr-- != begin)) { + lin.j = *itr; apply_visitor(lin, axes_[i]); } return lin.k; diff --git a/include/boost/histogram/histogram.hpp b/include/boost/histogram/histogram.hpp index aff7d565..e4fe602f 100644 --- a/include/boost/histogram/histogram.hpp +++ b/include/boost/histogram/histogram.hpp @@ -16,8 +16,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -99,11 +100,13 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_CTOR, nil * \throws std::range_error If the range doesn't fit the dimension of the histogram. */ template - inline void fill(boost::iterator_range range) + inline + typename boost::disable_if, void>::type + fill(Iterator begin, Iterator end) { - if(range.size() != dim()) + if(std::distance(begin, end) != dim()) throw std::range_error("wrong number of arguments at fill"); - const size_type k = pos(range); + const size_type k = pos(begin, end); if (k != uintmax_t(-1)) data_.increase(k); } @@ -113,7 +116,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_CTOR, nil void fill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x) ) \ { \ const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \ - fill(boost::make_iterator_range(boost::begin(buffer), boost::end(buffer)));\ + fill(boost::begin(buffer), boost::end(buffer)); \ } // generates fill functions taking 1 to AXIS_LIMT arguments @@ -143,11 +146,13 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_FILL, nil * */ template - inline void wfill(boost::iterator_range range, double w) + inline + typename boost::disable_if, void>::type + wfill(Iterator begin, Iterator end, double w) { - if (range.size() != dim()) + if (std::distance(begin, end) != dim()) throw std::range_error("wrong number of arguments"); - const size_type k = pos(range); + const size_type k = pos(begin, end); if (k != uintmax_t(-1)) data_.increase(k, w); } @@ -157,7 +162,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_FILL, nil void wfill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x), double w ) \ { \ const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \ - wfill(boost::make_iterator_range(boost::begin(buffer), boost::end(buffer)), w); \ + wfill(boost::begin(buffer), boost::end(buffer), w); \ } // generates wfill functions taking 1 to AXIS_LIMT arguments @@ -178,11 +183,13 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_WFILL, ni * \throws std::range_error if the length does not match the dimension */ template - inline double value(boost::iterator_range range) const + inline + typename boost::disable_if, double>::type + value(Iterator begin, Iterator end) const { - if (range.size() != dim()) + if (std::distance(begin, end) != dim()) throw std::range_error("wrong number of arguments"); - return data_.value(linearize(range)); + return data_.value(linearize(begin, end)); } #define BOOST_HISTOGRAM_VALUE(z, n, unused) \ @@ -191,9 +198,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_WFILL, ni const \ { \ const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \ - return value(boost::make_iterator_range( \ - boost::begin(idx), boost::end(idx) \ - )); /* size is checked here */ \ + return value(boost::begin(idx), boost::end(idx)); /* size is checked here */ \ } // generates value functions taking 1 to AXIS_LIMT arguments @@ -225,13 +230,14 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VALUE, ni * \throws std::range_error if the length does not match the dimension * */ - template - inline double variance(boost::iterator_range range) const + inline + typename boost::disable_if, double>::type + variance(Iterator begin, Iterator end) const { - if (range.size() != dim()) + if (std::distance(begin, end) != dim()) throw std::runtime_error("wrong number of arguments"); - return data_.variance(linearize(range)); + return data_.variance(linearize(begin, end)); } #define BOOST_HISTOGRAM_VARIANCE(z, n, unused) \ @@ -240,9 +246,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VALUE, ni const \ { \ const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \ - return variance(boost::make_iterator_range( \ - boost::begin(idx), boost::end(idx) \ - )); /* size is checked here */ \ + return variance(boost::begin(idx), boost::end(idx)); /* size is checked here */ \ } // generates variance functions taking 1 to AXIS_LIMT arguments diff --git a/src/python/histogram.cpp b/src/python/histogram.cpp index c7634410..d8a75615 100644 --- a/src/python/histogram.cpp +++ b/src/python/histogram.cpp @@ -124,7 +124,7 @@ histogram_fill(python::tuple args, python::dict kwargs) { for (unsigned i = 0; i < dims[0]; ++i) { double* v = reinterpret_cast(PyArray_GETPTR1(a, i) ); double* w = reinterpret_cast(PyArray_GETPTR1(aw, i)); - self.wfill(boost::make_iterator_range(v, v+self.dim()), *w); + self.wfill(v, v+self.dim(), *w); } Py_DECREF(aw); @@ -135,7 +135,7 @@ histogram_fill(python::tuple args, python::dict kwargs) { } else { for (unsigned i = 0; i < dims[0]; ++i) { double* v = reinterpret_cast(PyArray_GETPTR1(a, i)); - self.fill(boost::make_iterator_range(v, v+self.dim())); + self.fill(v, v+self.dim()); } } @@ -156,11 +156,11 @@ histogram_fill(python::tuple args, python::dict kwargs) { v[i] = extract(args[1 + i]); if (ow.is_none()) { - self.fill(boost::make_iterator_range(v, v+self.dim())); + self.fill(v, v+self.dim()); } else { const double w = extract(ow); - self.wfill(boost::make_iterator_range(v, v+self.dim()), w); + self.wfill(v, v+self.dim(), w); } return object(); @@ -185,7 +185,7 @@ histogram_value(python::tuple args, python::dict kwargs) { for (unsigned i = 0; i < self.dim(); ++i) idx[i] = extract(args[1 + i]); - return object(self.value(boost::make_iterator_range(idx, idx + self.dim()))); + return object(self.value(idx, idx + self.dim())); } python::object @@ -207,7 +207,7 @@ histogram_variance(python::tuple args, python::dict kwargs) { for (unsigned i = 0; i < self.dim(); ++i) idx[i] = extract(args[1 + i]); - return object(self.variance(boost::make_iterator_range(idx, idx + self.dim()))); + return object(self.variance(idx, idx + self.dim())); } class histogram_access {