11 #ifndef LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
12 #define LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
23 #include <type_traits>
71 public std::iterator<std::random_access_iterator_tag, T>
73 typedef std::iterator<std::random_access_iterator_tag, T>
base_t;
78 using typename base_t::value_type;
79 using typename base_t::difference_type;
150 template <
typename T>
185 template <
typename SIZE>
235 {
return (index >=
offset) && (index <
last); }
254 {
return (index >=
offset) && (index <=
last); }
292 template <
typename T>
466 template <typename T>
486 class const_reference;
488 class const_iterator;
491 class const_datarange_t;
510 { resize(new_size); }
518 nominal_size(0), ranges()
519 { add_range(
offset, from.begin(), from.end()); }
522 sparse_vector(sparse_vector
const&) =
default;
526 : nominal_size(
from.nominal_size)
527 , ranges(
std::move(
from.ranges))
528 {
from.nominal_size = 0; }
531 sparse_vector& operator=(sparse_vector
const&) =
default;
536 ranges = std::move(
from.ranges);
537 nominal_size =
from.nominal_size;
538 from.nominal_size = 0;
548 nominal_size(0), ranges()
553 ~sparse_vector() =
default;
558 void clear() { ranges.clear(); nominal_size = 0; }
562 size_type
size()
const {
return nominal_size; }
568 size_type
capacity()
const {
return nominal_size; }
572 void resize(size_type new_size);
574 void resize(size_type new_size, value_type def_value);
581 const_iterator
begin()
const;
582 const_iterator
end()
const;
588 value_type operator[] (size_type index)
const;
591 reference operator[] (size_type index);
607 bool is_void(size_type index)
const;
613 {
return ranges.empty() || (ranges.back().end_index() <
size()); }
617 size_type
count()
const;
634 value_type& set_at(size_type index, value_type
value);
637 void unset_at(size_type index);
653 if (is_zero(value, thr)) resize(
size() + 1);
654 else push_back(value);
668 template <
typename ITER>
669 void assign(ITER
first, ITER last) { clear(); append(first, last); }
678 template <
typename CONT>
679 void assign(
const CONT& new_data) { clear(); append(new_data); }
687 void assign(vector_t&& new_data) { clear(); append(std::move(new_data)); }
718 auto iterate_ranges() -> decltype(
auto);
721 size_type
n_ranges()
const {
return ranges.size(); }
724 const datarange_t&
range(
size_t i)
const {
return ranges[i]; }
749 auto range_data(std::size_t i);
750 auto range_data(std::size_t
const i)
const {
return range_const_data(i); }
754 auto range_const_data(std::size_t i)
const;
757 range_const_iterator
begin_range()
const {
return ranges.begin(); }
760 range_const_iterator
end_range()
const {
return ranges.end(); }
771 range_const_iterator find_range_iterator(size_type index)
const;
773 {
return ranges.begin() + find_range_number(index); }
784 {
return find_range_iterator(index) - begin_range(); }
794 const datarange_t& find_range(size_type index)
const;
795 datarange_t& find_range(size_type index);
805 datarange_t make_void_around(size_type index);
821 template <
typename ITER>
822 const datarange_t& add_range(size_type
offset, ITER
first, ITER last);
836 template <
typename CONT>
838 {
return add_range(offset, new_data.begin(), new_data.end()); }
853 const datarange_t& add_range(size_type
offset, vector_t&& new_data);
884 template <
typename ITER,
typename OP>
885 const datarange_t& combine_range(
887 value_type void_value = value_zero
904 template <
typename CONT,
typename OP>
906 size_type
offset,
const CONT& other, OP&& op,
907 value_type void_value = value_zero
910 return combine_range(offset, other.begin(), other.end(),
911 std::forward<OP>(op), void_value);
926 template <
typename ITER>
928 {
return add_range(
size(), first, last); }
939 template <
typename CONT>
940 const datarange_t&
append(
const CONT& range_data)
941 {
return add_range(
size(), range_data); }
953 const datarange_t&
append(vector_t&& range_data)
954 {
return add_range(
size(), std::move(range_data)); }
972 datarange_t void_range(range_iterator
const iRange);
974 {
return void_range(ranges.begin() + iRange); }
991 bool is_valid()
const;
995 void make_void(iterator
first, iterator last);
1007 static constexpr value_type value_zero{0};
1010 static value_type
abs(value_type v) {
return (v < value_zero)? -v: v; }
1013 static value_type
is_zero(value_type v) {
return v == value_zero; }
1016 static value_type
is_zero(value_type v, value_type thr)
1017 {
return abs(v - value_zero) <= thr; }
1021 {
return is_zero(
abs(a - b)); }
1024 static value_type
is_equal(value_type
a, value_type b, value_type thr)
1025 {
return is_zero(
abs(a - b), thr); }
1031 static size_t expected_vector_size(
size_t size);
1034 static size_t min_gap();
1037 static bool should_merge(
1038 const typename datarange_t::base_t&
a,
1039 const typename datarange_t::base_t& b
1057 {
return find_next_range_iter(index, ranges.begin()); }
1059 {
return find_next_range_iter(index, ranges.cbegin()); }
1070 range_iterator find_next_range_iter(size_type index, range_iterator rbegin);
1071 range_const_iterator find_next_range_iter
1072 (size_type index, range_const_iterator rbegin)
const;
1088 range_iterator find_range_iter_at_or_after(size_type index);
1089 range_const_iterator find_range_iter_at_or_after(size_type index)
const;
1112 {
return find_extending_range_iter(index, ranges.begin()); }
1114 {
return find_extending_range_iter(index, ranges.cbegin()); }
1128 range_iterator find_extending_range_iter
1129 (size_type index, range_iterator rbegin);
1130 range_const_iterator find_extending_range_iter
1131 (size_type index, range_const_iterator rbegin)
const;
1136 {
return ranges.empty()? 0: ranges.back().end_index(); }
1140 range_iterator
insert_range(range_iterator iInsert,
const datarange_t& data)
1141 {
return data.empty()? iInsert: ranges.insert(iInsert, data); }
1143 {
return data.empty()? iInsert: ranges.insert(iInsert, std::move(data)); }
1147 const datarange_t& add_range_before
1148 (size_type
offset, vector_t&& new_data, range_iterator nextRange);
1151 range_iterator eat_range_head(range_iterator iRange,
size_t index);
1165 datarange_t& merge_ranges(range_iterator iRange);
1168 size_type fix_size();
1191 template <
typename T>
1192 std::ostream& operator<< (std::ostream& out, const lar::sparse_vector<T>& v);
1201 template <
typename T>
1216 template <
typename ITER>
1231 {
return values.begin() + index - base_t::begin_index(); }
1233 {
return get_const_iterator(index); }
1235 {
return values.begin() + index - base_t::begin_index(); }
1251 {
values.resize(new_size); fit_size_from_data(); }
1253 {
values.resize(new_size, def_value); fit_size_from_data(); }
1259 {
return values[base_t::relative_index(index)]; }
1261 {
return values[base_t::relative_index(index)]; }
1278 template <
typename ITER>
1294 { resize(base_t::relative_index(to_index), def_value); }
1307 template <
typename Stream>
1308 void dump(
Stream&& out)
const;
1324 template <
typename T>
1332 using datarange_t::last;
1333 using datarange_t::begin_index;
1334 using datarange_t::end_index;
1335 using datarange_t::relative_index;
1338 using datarange_t::includes;
1340 using datarange_t::separate;
1341 using datarange_t::borders;
1342 using datarange_t::operator<;
1343 using datarange_t::operator==;
1344 using datarange_t::is_valid;
1345 using datarange_t::less;
1349 using datarange_t::get_iterator;
1356 using datarange_t::operator[];
1357 using datarange_t::dump;
1368 {
return static_cast<datarange_t
const&
>(*this); }
1382 template <
typename T>
1390 explicit operator value_type()
const {
return ptr? *ptr: value_zero; }
1392 {
return ptr? *ptr: value_zero; }
1403 template <
typename T>
1417 {
return const_cast<value_type&
>(*const_reference::ptr) = v; }
1420 {
return const_cast<value_type&
>(*const_reference::ptr); }
1430 template <
typename T>
1470 cont(&c), index(
std::min(offset, c.
size())), currentRange()
1471 { refresh_state(); }
1475 cont(&c), index(0), currentRange(c.get_ranges().
begin())
1480 cont(&c), index(c.
size()), currentRange(c.get_ranges().
end())
1485 {
return (*cont)[index +
offset]; }
1512 {
return (cont == as.
cont) && (index == as.
index); }
1514 {
return (cont != as.
cont) || (index != as.
index); }
1516 {
return (cont == than.
cont) && (index < than.
index); }
1518 {
return (cont == than.
cont) && (index > than.
index); }
1520 {
return (cont == than.
cont) && (index <= than.
index); }
1522 {
return (cont == than.
cont) && (index >= than.
index); }
1564 void refresh_state();
1579 template <
typename T>
1606 {
return (*const_iterator::cont)[const_iterator::index +
offset]; }
1629 {
return reference(const_iterator::operator*()); }
1647 namespace lar::details {
1651 template <
typename BITER,
typename EITER>
1658 auto const&
end()
const {
return e; }
1664 template <
typename T>
1671 template <
typename T>
1683 {
return make_const_datarange_t<T>(*it); }
1685 {
return it != other.
it; }
1697 template <
typename T>
1701 template <
typename T>
1702 decltype(
auto) lar::sparse_vector<T>::iterate_ranges() {
1703 return details::iteratorRange(
1704 details::const_datarange_iterator<T>(ranges.begin()),
1705 details::const_datarange_iterator<T>(ranges.end())
1709 template <
typename T>
1711 if (new_size >=
size()) {
1712 nominal_size = new_size;
1718 ranges.erase(iLastRange, ranges.end());
1719 if (!ranges.empty()) {
1721 if (new_size == iLastRange->begin_index())
1722 ranges.erase(iLastRange);
1723 else if (new_size < iLastRange->end_index())
1724 iLastRange->resize(new_size - iLastRange->begin_index());
1728 nominal_size = new_size;
1732 template <
typename T>
1734 if (new_size ==
size())
return;
1735 if (new_size >
size()) {
1740 ranges.back().resize(new_size - ranges.back().begin_index(), def_value);
1742 nominal_size = new_size;
1750 template <
typename T>
1754 template <
typename T>
1758 template <
typename T>
1763 template <
typename T>
1768 template <
typename T>
1777 if (iNextRange == ranges.begin())
return value_zero;
1783 return (index < range.
end_index())? range[index]: value_zero;
1787 template <
typename T>
1796 if (iNextRange == ranges.begin())
return reference();
1806 template <
typename T>
1808 if (ranges.empty() || (index >=
size()))
1809 throw std::out_of_range(
"empty sparse vector");
1812 return ((iNextRange == ranges.begin())
1813 || ((--iNextRange)->end_index() <= index));
1817 template <
typename T>
1821 return std::accumulate(begin_range(), end_range(),
size_type(0),
1827 template <
typename T>
1836 if (iNextRange != ranges.begin()) {
1842 if (index < range.
end_index())
return range[index] = value;
1845 return const_cast<datarange_t&
>(add_range(index, { value }))[index];
1849 template <
typename T>
1856 if (iNextRange == ranges.begin())
return;
1865 if (range.
size() == 1) ranges.erase(iNextRange);
1869 else if (index == range.
end_index() - 1)
1876 ranges.emplace(++iNextRange, index + 1,
1886 template <
typename T>
1890 template <
typename T>
1895 template <
typename T>
1899 if (ranges.empty())
throw std::out_of_range(
"empty sparse vector");
1902 return ((iNextRange == ranges.begin())
1903 || (index >= (--iNextRange)->end_index()))?
1904 ranges.end(): iNextRange;
1908 template <
typename T>
1912 if (ranges.empty())
throw std::out_of_range(
"empty sparse vector");
1915 if (iNextRange == ranges.end())
1916 throw std::out_of_range(
"index in no range of the sparse vector");
1920 template <
typename T>
1925 (
const_cast<const this_t*
>(
this)->find_range(index));
1929 template <
typename T>
1931 if (ranges.empty() || (index >=
size()))
1932 throw std::out_of_range(
"empty sparse vector");
1935 if ((iNextRange == ranges.begin())
1936 || ((--iNextRange)->end_index() <= index))
1940 return void_range(iNextRange);
1944 template <
typename T>
template <
typename ITER>
1952 if ((iInsert != ranges.begin()) && std::prev(iInsert)->borders(offset)) {
1954 (--iInsert)->extend(offset, first, last);
1959 iInsert = insert_range(iInsert, {
offset,
first, last });
1961 return merge_ranges(iInsert);
1965 template <
typename T>
1970 return add_range_before(offset, std::move(new_data),
1972 ranges.begin(), ranges.end(),
offset,
1973 typename datarange_t::less_int_range(datarange_t::less)
1980 template <
typename T>
1981 template <
typename ITER,
typename OP>
1983 size_type offset, ITER first, ITER last, OP&& op,
2002 auto const insertionPoint =
offset;
2003 auto destRange = find_range_iter_at_or_after(offset);
2004 while (src != last) {
2010 if ((destRange != end_range()) && destRange->includes(offset)) {
2012 auto dest = destRange->get_iterator(offset);
2014 auto const end = destRange->end();
2015 while (src != last) {
2016 *dest = op(*dest, *src);
2019 if (++dest ==
end)
break;
2021 if (src == last)
break;
2022 offset = destRange->end_index();
2034 size_type const newRangeSize = (destRange == end_range())
2039 combinedData.reserve(newRangeSize);
2041 while (i++ < newRangeSize) {
2042 combinedData.push_back(op(void_value, *src));
2043 if (++src == last)
break;
2047 destRange = insert_range(destRange, {
offset, std::move(combinedData) });
2052 offset = destRange->end_index();
2063 (find_extending_range_iter(insertionPoint == 0? 0: insertionPoint - 1));
2068 template <
typename T>
2073 if ((first.
cont !=
this) || (last.
cont !=
this)) {
2074 throw std::runtime_error
2075 (
"lar::sparse_vector::make_void(): iterators from alien container");
2078 if (first >= last)
return;
2087 if (first_range == ranges.end())
return;
2090 if (first.
index > first_range->begin_index()) {
2091 if (first_range == last_range) {
2095 last_range = ranges.emplace(++last_range, last.
index,
2096 first_range->begin() + first_range->relative_index(last.
index),
2100 first_range->move_tail(first.
index);
2103 first_range->move_tail(first.
index);
2109 if ((last_range != ranges.end()) && (last.
index > last_range->begin_index()))
2110 eat_range_head(last_range, last.
index);
2113 ranges.erase(first_range, last_range);
2117 template <
typename T>
2119 auto r { std::move(*iRange) };
2120 ranges.erase(iRange);
2125 template <
typename T>
2128 if (ranges.empty())
return true;
2131 while (iNext != rend) {
2133 if (iRange->empty())
return false;
2134 if (iNext != rend) {
2135 if (!(*iRange < *iNext))
return false;
2136 if (!iRange->separate(*iNext))
return false;
2139 if (nominal_size < ranges.back().end_index())
return false;
2147 template <
typename T>
2153 return std::upper_bound(
2154 rbegin, ranges.end(), index,
2155 typename datarange_t::less_int_range(datarange_t::less)
2159 template <
typename T>
2165 return std::upper_bound(
2166 rbegin, ranges.end(), index,
2167 typename datarange_t::less_int_range(datarange_t::less)
2172 template <
typename T>
2177 auto after = find_next_range_iter(index);
2179 return ((after != ranges.begin()) && (index < std::prev(after)->end_index()))
2180 ? std::prev(after): after;
2184 template <
typename T>
2189 auto after = find_next_range_iter(index);
2191 return ((after != ranges.begin()) && (index < std::prev(after)->end_index()))
2192 ? std::prev(after): after;
2196 template <
typename T>
2202 auto it = find_next_range_iter(index, rbegin);
2205 return ((it != rbegin) && std::prev(it)->borders(index))? std::prev(it): it;
2209 template <
typename T>
2215 auto it = find_next_range_iter(index, rbegin);
2218 return ((it != rbegin) && std::prev(it)->borders(index))? std::prev(it): it;
2222 template <
typename T>
2230 if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
2232 (--iInsert)->extend(offset, new_data.begin(), new_data.end());
2240 iInsert = insert_range(iInsert, {
offset, std::move(new_data) });
2242 return merge_ranges(iInsert);
2246 template <
typename T>
2251 while (iNext != ranges.end()) {
2252 if (!iRange->borders(iNext->begin_index()))
break;
2255 if (iNext->end_index() > iRange->end_index()) {
2257 (iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
2259 iNext = ranges.erase(iNext);
2266 template <
typename T>
2270 if (index <= iRange->begin_index())
return iRange;
2271 if (index >= iRange->end_index())
return ranges.erase(iRange);
2272 iRange->move_head(index);
2277 template <
typename T>
2279 if (!ranges.empty())
2280 nominal_size = std::max(nominal_size, ranges.back().end_index());
2281 return nominal_size;
2287 template <
typename T>
2293 + std::max(
size_t(32), (
alignof(
datarange_t)*size + 8));
2297 template <
typename T>
2307 template <
typename T>
2316 return expected_vector_size(a.
size() + b.
size() + gap_size)
2317 <= expected_vector_size(a.
size()) + expected_vector_size(b.
size());
2323 template <
typename T>
2324 std::ostream& operator<< (std::ostream& out, const lar::sparse_vector<T>& v) {
2326 out <<
"Sparse vector of size " << v.size() <<
" with "
2327 << v.get_ranges().size() <<
" ranges:";
2329 iRange = v.begin_range(), rend = v.end_range();
2330 while (iRange != rend) {
2342 return out << std::endl;
2350 template <
typename T>
template <
typename ITER>
2357 base_t::resize(new_size);
2359 std::copy(first, last, get_iterator(index));
2364 template <
typename T>
2369 if (delta == 0)
return;
2370 base_t::move_head(delta);
2382 template <
typename T>
2383 template <
typename Stream>
2385 out <<
"[" << this->begin_index() <<
" - " << this->end_index() <<
"] ("
2386 << this->
size() <<
"): {";
2387 for (
auto const& v: this->
values) out <<
" " << v;
2395 template <
typename T>
2400 if (!cont || (index >= cont->size()))
return *
this;
2406 if (currentRange != cont->ranges.end()) {
2408 if (currentRange->end_index() <= index) ++currentRange;
2415 template <
typename T>
2419 if (!cont)
throw std::out_of_range(
"iterator to no sparse vector");
2422 if (index >= cont->size())
return value_zero;
2425 if (currentRange == cont->ranges.end())
return value_zero;
2428 if (index < currentRange->begin_index())
return value_zero;
2430 return (*currentRange)[index];
2434 template <
typename T>
2438 if (delta == 1)
return this->operator++();
2440 if ((currentRange == cont->ranges.end())
2441 || !currentRange->includes(index)
2447 template <
typename T>
2453 template <
typename T>
2457 if ((currentRange == cont->ranges.end())
2458 || !currentRange->includes(index + delta)
2462 iter.
index += delta;
2466 template <
typename T>
2473 template <
typename T>
2478 if (cont != iter.cont) {
2479 throw std::runtime_error(
"lar::sparse_vector::const_iterator:"
2480 " difference with alien iterator");
2482 return index -iter.index;
2486 template <
typename T>
2492 currentRange = cont->find_next_range_iter(index);
2494 if (currentRange != cont->ranges.begin()) {
2495 if ((currentRange - 1)->end_index() > index) --currentRange;
2512 #endif // LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
static void static_check()
void clear()
Removes all the data, making the vector empty.
iterator(const container_t &c, const typename special::begin _)
Special constructor: initializes at the beginning of the container.
bool includes(const range_t &r) const
Returns whether the specified range is completely included in this one.
std::vector< value_type > vector_t
type of STL vector holding this data
sparse_vector(const vector_t &from, size_type offset=0)
Constructor: a solid vector from an existing STL vector.
sparse_vector()
Default constructor: an empty vector.
bool operator!=(const this_t &as) const
void refresh_state()
Reassigns the internal state according to the index.
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
const datarange_t & add_range(size_type offset, const CONT &new_data)
Copies the elements in container to a range with specified offset.
Iterator to the sparse vector values.
vector_t::const_pointer const_pointer
bool operator<(const range_t &than) const
Sort: this range is smaller if its offset is smaller.
void set(size_type from, size_type to)
Sets the borders of the range.
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
size_type n_ranges() const
Returns the internal list of non-void ranges.
reference(value_type &value)
container_t::pointer pointer
bool operator>=(const this_t &as) const
static size_t expected_vector_size(size_t size)
Returns the expected size taken by a vector of specified size.
const_datarange_iterator & operator++()
const_reference(const value_type *pValue=0)
size_type fix_size()
Extends the vector size according to the last range.
void resize(size_type new_size)
Resizes the vector to the specified size, adding void.
void dump(Stream &&out) const
Dumps the content of this data range into a stream.
const datarange_t & append(const CONT &range_data)
Adds a sequence of elements as a range at the end of the vector.
const_reference operator*() const
Constant dereferenciation operator.
static value_type abs(value_type v)
Returns the module of the specified value.
vector_t values
data in the range
const_value_box< T > this_t
this_t operator-(difference_type ofs) const
Returns an iterator pointing behind this one by the specified steps.
reference(const const_reference &from)
size_type size() const
Returns the size of the vector.
this_t operator++(int)
Increments the position of the iterator, returns the old position.
A class representing a cell in a sparse vector.
vector_t::pointer pointer
iterator(container_t &c, size_type offset=0)
Constructor from a container and an offset.
size_type offset
offset (absolute index) of the first element
range_iterator eat_range_head(range_iterator iRange, size_t index)
Voids the starting elements up to index (excluded) of a given range.
constexpr bool operator<(CryostatID const &a, CryostatID const &b)
Order cryostats with increasing ID.
std::iterator< std::random_access_iterator_tag, T > base_t
base type
const_iterator & operator+=(difference_type delta)
Increment and decrement operators.
value_type value
value to be returned when dereferencing
decltype(auto) make_const_datarange_t(typename sparse_vector< T >::datarange_t &r)
size_type minimum_size() const
Returns the size determined by the ranges already present.
auto range_const_data(std::size_t i) const
Like range_data() but with explicitly read-only access to data.
void resize(size_t new_size)
Resizes the range (optionally filling the new elements with def_value)
range_t< size_type > base_t
base class
const_iterator::const_reference const_reference
const container_t * cont
pointer to the container
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
std::size_t size(FixedBins< T, C > const &) noexcept
constexpr bool operator>=(Interval< Q, Cat > const a, Quantity< Args...> const b) noexcept
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
iterator & operator++()
Increment and decrement operators.
value_type operator[](difference_type) const
Returns a copy of the stored value.
reference(value_type *pValue=0)
range_const_iterator find_extending_range_iter(size_type index) const
value_type & operator=(value_type v)
const vector_t & data() const
Return the vector of data values.
const_iterator cend() const
range_const_iterator find_next_range_iter(size_type index) const
const datarange_t & add_range_before(size_type offset, vector_t &&new_data, range_iterator nextRange)
Implementation detail of add_range(), with where to add the range.
auto const & size() const
value_const_iterator< T > operator+(typename value_const_iterator< T >::difference_type ofs, value_const_iterator< T > &iter)
Returns an iterator pointing ahead of this one by the specified steps.
size_type begin_index() const
Returns the first absolute index included in the range.
this_t operator--(int)
Decrements the position of the iterator, returns the old position.
auto range_data(std::size_t i)
Provides direct access to data of i-th non-void range (zero-based)
const_reference(const value_type &value)
container_t::difference_type difference_type
datarange_t void_range(std::size_t const iRange)
const_iterator(const container_t &c, const typename special::end)
Special constructor: initializes at the end of the container.
value_type & set_at(size_type index, value_type value)
Writes into an element (creating or expanding a range if needed)
bool operator==(const this_t &as) const
Comparison operators: determined by the position pointed by the iterators.
T value_type
type of the stored values
bool is_void(size_type index) const
Returns whether the specified position is void.
bool(* less_int_range)(size_type, const range_t &b)
Helper type to be used for binary searches.
bool separate(const range_t &r) const
Returns if there are elements in between this and the specified range.
const_iterator get_iterator(size_type index) const
Iterator to the sparse vector values.
bool overlap(const range_t &r) const
Returns if this and the specified range overlap.
datarange_t(size_type offset, ITER first, ITER last)
Constructor: offset and data.
void move_tail(size_type to_index, value_type def_value=value_zero)
Moves the end of this range.
const_datarange_t & operator*() const
const_datarange_iterator(base_iterator it)
const datarange_t & combine_range(size_type offset, const CONT &other, OP &&op, value_type void_value=value_zero)
Combines the elements in container with the data at offset.
ranges_const_iterator currentRange
pointer to the current (or next) range
bool is_valid() const
Returns if the vector is in a valid state.
bool operator!=(const_datarange_iterator const &other) const
void fit_size_from_data()
size_type end_index() const
Returns the first absolute index not included in the range.
QuadExpr operator-(double v, const QuadExpr &e)
void move_head(difference_type shift)
Moves the begin of the range by the specified amount.
sparse_vector(sparse_vector &&from)
Move constructor.
range_iterator find_extending_range_iter(size_type index)
Returns an iterator to the range no earlier than index, or end() if none.
container_t::size_type size_type
range_t(size_type from, size_type to)
Constructor from first and last index.
static bool should_merge(const typename datarange_t::base_t &a, const typename datarange_t::base_t &b)
Returns if merging the two specified ranges would save memory.
void move_tail(difference_type shift)
Moves the end of the range by the specified amount.
const_iterator cbegin() const
bool operator<(const this_t &as) const
bool empty() const
Returns whether the range is empty.
const_iterator(const container_t &c, const typename special::begin)
Special constructor: initializes at the beginning of the container.
datarange_t(const base_t &range)
Constructor: range initialized with 0.
const_value_box(value_type new_value)
Constructor: stores the specified value.
bool operator<=(const this_t &as) const
const_iterator cend() const
range_list_t ranges
list of ranges
bool back_is_void() const
Returns whether the sparse vector ends with void.
vector_t::difference_type difference_type
index difference type
iterator(const_iterator from)
sparse_vector(size_type new_size)
Constructor: a vector with new_size elements in the void.
A range (interval) of integers.
this_t & operator--()
Decrements the position of the iterator, returns the new position.
vector_t::iterator iterator
static size_t min_gap()
Minimum optimal gap between ranges (a guess)
iterator get_iterator(size_type index)
Returns an iterator to the specified absolute value (no check!)
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
sparse_vector & operator=(sparse_vector &&from)
Move assignment.
Namespace for special initialization.
datarange_t()
Default constructor: an empty range.
static bool less(const range_t &a, const range_t &b)
Returns if a is "less" than b.
const_iterator get_const_iterator(size_type index) const
datarange_t & extend(size_type index, ITER first, ITER last)
Appends the specified elements to this range.
value_const_iterator(value_type new_value, difference_type offset)
Constructor: value to be returned and current iterator "position".
vector_t::size_type size_type
size type
typename sparse_vector< T >::const_datarange_t const_datarange_t
void assign(const CONT &new_data)
Copies data from a container.
const_iterator operator-(difference_type delta) const
this_t & operator++()
Increments the position of the iterator, returns the new position.
value_const_iterator()
Default constructor: use the default value.
std::vector< datarange_t > range_list_t
type of sparse vector data
range_iterator find_range_iter_at_or_after(size_type index)
Returns an iterator to the range at or after index.
Little class storing a value.
void make_void(iterator first, iterator last)
Makes all the elements from first and before last void.
vector_t::const_reference const_reference
const_iterator & operator++()
Increment and decrement operators.
container_t::range_list_t::const_iterator ranges_const_iterator
auto end(FixedBins< T, C > const &) noexcept
this_t & operator-=(difference_type ofs)
Decrements the position of the iterator by the specified steps.
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following contiguous ranges.
bool operator!=(base_iterator< ValueL > const &a, base_iterator< ValueR > const &b)
const vector_t & data() const
Return the vector of data values (only constant access).
range_iterator insert_range(range_iterator iInsert, const datarange_t &data)
Plug a new data range in the specified position; no check performed.
void move_head(size_type to_index, value_type def_value=value_zero)
Moves the begin of this range.
String & operator+=(String &s, VectorDumper< Vector > const &manip)
Appends a string rendering of a vector to the specified string.
container_t::reference reference
range_const_iterator begin_range() const
Returns a constant iterator to the first data range.
range_t()
Default constructor: empty range.
const datarange_t & append(ITER first, ITER last)
Adds a sequence of elements as a range at the end of the vector.
void push_back(value_type value, value_type thr)
Adds one element to the end of the vector (if zero, just adds void)
sparse_vector(vector_t &&from, size_type offset=0)
Constructor: a solid vector from an existing STL vector.
bool is_valid() const
Returns whether the range is valid (that is, non-negative size)
value_type operator*() const
Returns a copy of the stored value.
size_type index
pointer to the current value, as absolute index
sparse_vector< T > this_t
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
const_iterator operator++(int)
const_iterator & operator-=(difference_type delta)
static value_type is_zero(value_type v)
Returns whether the value is exactly zero.
const datarange_t & combine_range(size_type offset, ITER first, ITER last, OP &&op, value_type void_value=value_zero)
Combines a sequence of elements as a range with data at offset.
A constant reference to a data range.
iterator operator++(int _)
difference_type index
(arbitrary) position pointed by the iterator
const_iterator()
Default constructor, does not iterate anywhere.
void resize(size_t new_size, value_type def_value)
this_t operator+(difference_type ofs) const
Returns an iterator pointing ahead of this one by the specified steps.
auto begin(FixedBins< T, C > const &) noexcept
datarange_t make_void_around(size_type index)
Casts the whole range with the specified item into the void.
const datarange_t & append(vector_t &&range_data)
Adds a sequence of elements as a range at the end of the vector.
value_const_iterator< T > this_t
alias for this type
iterator()
Default constructor, does not iterate anywhere.
size_type size() const
Returns the size of the range.
constexpr bool operator>(Interval< Q, Cat > const a, Quantity< Args...> const b) noexcept
static bool less(const range_t &a, size_type b)
static bool less(size_type a, const range_t &b)
typename datarange_t::less_int_range less_int_range
range_const_iterator find_range_iterator(size_type index) const
Returns an iterator to the range containing the specified index.
SIZE size_type
type for the indices in the range
sparse_vector< T > container_t
size_type nominal_size
current size
const datarange_t & find_range(size_type index) const
Returns the range containing the specified index.
QuadExpr operator+(double v, const QuadExpr &e)
iteratorRange(BITER const &b, EITER const &e)
this_t & operator=(value_type)
Assignment: the assigned value is ignored.
vector_t::const_iterator const_iterator
range_iterator find_range_iterator(size_type index)
bool empty() const
Returns whether the vector is empty.
then echo File list $list not found else cat $list while read file do echo $file sed s
const_iterator(const container_t &c, size_type offset)
Constructor from a container and a offset.
Special little box to allow void elements to be treated as references.
void unset_at(size_type index)
Casts the element with the specified index into the void.
Enclosure to use two iterators representing a range in a range-for loop.
void assign(vector_t &&new_data)
Moves data from a vector.
range_const_iterator get_current_range() const
Returns the current range internal value; use it at your own risk!!
auto range_data(std::size_t const i) const
const_value_box()
Default constructor: stores default value.
auto const & begin() const
std::size_t find_range_number(size_type index) const
Returns the number (0-based) of range containing index.
reference operator*() const
Dereferenciation operator (can't write non-empty elements!)
const_iterator::special special
iterator begin()
Standard iterators interface.
Range class, with range and data.
value_type value
the value stored for delivery
void resize(size_type new_size)
Moves the end of the range to fit the specified size.
datarange_t(size_type offset, vector_t &&data)
Constructor: offset and data as a vector (which will be used directly)
const_iterator end() const
static value_type is_zero(value_type v, value_type thr)
Returns whether the value is zero below a given threshold.
range_iterator insert_range(range_iterator iInsert, datarange_t &&data)
std::forward_iterator_tag iterator_category
range_const_iterator end_range() const
Returns a constant iterator to after the last data range.
bool includes(size_type index) const
Returns whether the specified absolute index is included in this range.
static value_type is_equal(value_type a, value_type b)
Returns whether two values are the same.
range_list_t::iterator range_iterator
type of iterator over ranges
const_iterator begin() const
value_const_iterator(value_type new_value)
Constructor: value that will be returned.
iterator(const container_t &c, const typename special::end _)
Special constructor: initializes at the end of the container.
container_t::value_type value_type
void push_back(value_type value)
const_iterator cbegin() const
iterator begin()
begin and end iterators
std::size_t count(Cont const &cont)
const_iterator::reference reference
size_type last
offset (absolute index) after the last element
const_iterator::container_t container_t
QuadExpr operator*(double v, const QuadExpr &e)
bool operator>(const this_t &as) const
const_iterator operator+(difference_type delta) const
bool optimize()
Performs internal optimization, returns whether the object was changed.
datarange_t void_range(range_iterator const iRange)
Turns the specified range into void.
bool empty(FixedBins< T, C > const &) noexcept
void assign(ITER first, ITER last)
Copies data from a sequence between two iterators.
A constant iterator returning always the same value.
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
T value_type
type of the value stored
bool operator==(const range_t &as) const
Returns whether the specified range has our same offset and size.
constexpr bool operator<=(Interval< Q, Cat > const a, Quantity< Args...> const b) noexcept
std::ptrdiff_t difference_type
type for index difference
size_type capacity() const
Returns the capacity of the vector (compatibility only)
static value_type is_equal(value_type a, value_type b, value_type thr)
Returns whether two values are the same below a given threshold.
size_type relative_index(size_type index) const
Returns the position within the range of the absolute index specified.
bool borders(size_type index) const
Returns whether an index is within or immediately after this range.
this_t & operator+=(difference_type ofs)
Increments the position of the iterator by the specified steps.
size_type count() const
Returns the number of non-void cells.