10 #ifndef LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H 11 #define LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H 20 #include <type_traits> 57 operator const value_type&()
const {
return value; }
85 : index(offset),
value(new_value)
169 template <
typename T>
202 template <
typename SIZE>
217 range_t(size_type from, size_type to) : offset(from), last(
std::max(from, to)) {}
220 void set(size_type from, size_type to)
223 last = std::max(from, to);
236 size_type
size()
const {
return last - offset; }
239 void resize(size_type new_size) { last = offset + new_size; }
242 void move_head(difference_type shift) { offset += shift; }
245 void move_tail(difference_type shift) { last += shift; }
248 bool empty()
const {
return last <= offset; }
251 bool includes(size_type index)
const {
return (index >= offset) && (index < last); }
275 bool borders(size_type index)
const {
return (index >= offset) && (index <= last); }
296 typedef bool (*less_int_range)(size_type,
const range_t& b);
304 template <
typename T>
308 template <
typename T>
480 template <typename T>
500 class const_reference;
505 class const_datarange_t;
530 add_range(offset, from.begin(), from.end());
534 sparse_vector(sparse_vector
const&) =
default;
540 from.nominal_size = 0;
544 sparse_vector&
operator=(sparse_vector
const&) =
default;
549 ranges = std::move(from.ranges);
550 nominal_size = from.nominal_size;
551 from.nominal_size = 0;
562 add_range(offset, std::move(from));
566 ~sparse_vector() =
default;
577 size_type
size()
const {
return nominal_size; }
583 size_type
capacity()
const {
return nominal_size; }
586 void resize(size_type new_size);
589 void resize(size_type new_size, value_type def_value);
603 value_type operator[](size_type index)
const;
606 reference operator[](size_type index);
621 bool is_void(size_type index)
const;
628 size_type count()
const;
644 value_type& set_at(size_type index, value_type
value);
647 void unset_at(size_type index);
650 void push_back(value_type value) { resize(
size() + 1, value); }
663 if (is_zero(value, thr))
679 template <
typename ITER>
693 template <
typename CONT>
709 append(std::move(new_data));
740 auto iterate_ranges() -> decltype(
auto);
771 auto range_data(std::size_t i);
772 auto range_data(std::size_t
const i)
const {
return range_const_data(i); }
776 auto range_const_data(std::size_t i)
const;
792 range_const_iterator find_range_iterator(size_type index)
const;
795 return ranges.begin() + find_range_number(index);
808 return find_range_iterator(index) - begin_range();
819 const datarange_t& find_range(size_type index)
const;
820 datarange_t& find_range(size_type index);
830 datarange_t make_void_around(size_type index);
846 template <
typename ITER>
847 const datarange_t& add_range(size_type offset, ITER first, ITER last);
861 template <
typename CONT>
862 const datarange_t&
add_range(size_type offset,
const CONT& new_data)
864 return add_range(offset, new_data.begin(), new_data.end());
880 const datarange_t& add_range(size_type offset, vector_t&& new_data);
911 template <
typename ITER,
typename OP>
912 const datarange_t& combine_range(size_type offset,
916 value_type void_value = value_zero);
932 template <
typename CONT,
typename OP>
936 value_type void_value = value_zero)
938 return combine_range(offset, other.begin(), other.end(), std::forward<OP>(op), void_value);
953 template <
typename ITER>
954 const datarange_t&
append(ITER first, ITER last)
956 return add_range(
size(), first, last);
968 template <
typename CONT>
969 const datarange_t&
append(
const CONT& range_data)
971 return add_range(
size(), range_data);
984 const datarange_t&
append(vector_t&& range_data)
986 return add_range(
size(), std::move(range_data));
1004 datarange_t void_range(range_iterator
const iRange);
1027 bool optimize() {
return optimize(min_gap()); }
1034 static constexpr value_type value_zero{0};
1037 static value_type
abs(value_type v) {
return (v < value_zero) ? -v : v; }
1040 static value_type
is_zero(value_type v) {
return v == value_zero; }
1043 static value_type
is_zero(value_type v, value_type thr) {
return abs(v - value_zero) <= thr; }
1046 static value_type
is_equal(value_type a, value_type b) {
return is_zero(
abs(a - b)); }
1049 static value_type
is_equal(value_type a, value_type b, value_type thr)
1051 return is_zero(
abs(a - b), thr);
1058 static size_t expected_vector_size(
size_t size);
1061 static size_t min_gap();
1064 static bool should_merge(
const typename datarange_t::base_t& a,
1065 const typename datarange_t::base_t& b);
1082 return find_next_range_iter(index, ranges.begin());
1086 return find_next_range_iter(index, ranges.cbegin());
1098 range_iterator find_next_range_iter(size_type index, range_iterator rbegin);
1099 range_const_iterator find_next_range_iter(size_type index, range_const_iterator rbegin)
const;
1115 range_iterator find_range_iter_at_or_after(size_type index);
1116 range_const_iterator find_range_iter_at_or_after(size_type index)
const;
1140 return find_extending_range_iter(index, ranges.begin());
1144 return find_extending_range_iter(index, ranges.cbegin());
1159 range_iterator find_extending_range_iter(size_type index, range_iterator rbegin);
1160 range_const_iterator find_extending_range_iter(size_type index,
1161 range_const_iterator rbegin)
const;
1165 size_type
minimum_size()
const {
return ranges.empty() ? 0 : ranges.back().end_index(); }
1168 range_iterator insert_range(range_iterator iInsert,
const datarange_t& data)
1171 return data.empty() ? iInsert : ranges.insert(iInsert, data);
1175 return data.empty() ? iInsert : ranges.insert(iInsert, std::move(data));
1180 const datarange_t& add_range_before(size_type offset,
1181 vector_t&& new_data,
1182 range_iterator nextRange);
1185 range_iterator eat_range_head(range_iterator iRange,
size_t index);
1199 datarange_t& merge_ranges(range_iterator iRange);
1202 size_type fix_size();
1223 template <
typename T>
1224 std::ostream& operator<<(std::ostream& out, const lar::sparse_vector<T>& v);
1231 template <
typename T>
1246 template <
typename ITER>
1248 : base_t(offset, offset +
std::distance(first, last)),
values(first, last)
1253 : base_t(offset, offset + data.
size()),
values(data)
1257 iterator get_iterator(
size_type index) {
return values.begin() + index - base_t::begin_index(); }
1262 return values.begin() + index - base_t::begin_index();
1277 void resize(
size_t new_size)
1281 fit_size_from_data();
1285 values.resize(new_size, def_value);
1286 fit_size_from_data();
1295 return values[base_t::relative_index(index)];
1313 template <
typename ITER>
1330 resize(base_t::relative_index(to_index), def_value);
1344 template <
typename Stream>
1345 void dump(Stream&& out)
const;
1359 template <
typename T>
1366 using datarange_t::begin_index;
1367 using datarange_t::borders;
1369 using datarange_t::end_index;
1370 using datarange_t::includes;
1371 using datarange_t::last;
1372 using datarange_t::offset;
1373 using datarange_t::overlap;
1374 using datarange_t::relative_index;
1375 using datarange_t::separate;
1377 using datarange_t::operator<;
1378 using datarange_t::operator==;
1380 using datarange_t::less;
1384 using datarange_t::get_iterator;
1391 using datarange_t::operator[];
1392 using datarange_t::dump;
1400 friend decltype(
auto) details::make_const_datarange_t<T>(
datarange_t&);
1414 template <
typename T>
1423 explicit operator value_type()
const {
return ptr ? *ptr : value_zero; }
1424 operator const value_type&()
const {
return ptr ? *ptr : value_zero; }
1434 template <
typename T>
1458 template <
typename T>
1496 : cont(&c), index(
std::min(offset, c.
size())), currentRange()
1503 : cont(&c), index(0), currentRange(c.get_ranges().
begin())
1508 : cont(&c), index(c.
size()), currentRange(c.get_ranges().
end())
1512 const_reference
operator[](size_type offset)
const {
return (*cont)[index + offset]; }
1543 return (cont == as.
cont) && (index == as.
index);
1547 return (cont != as.
cont) || (index != as.
index);
1551 return (cont == than.
cont) && (index < than.
index);
1555 return (cont == than.
cont) && (index > than.
index);
1559 return (cont == than.
cont) && (index <= than.
index);
1563 return (cont == than.
cont) && (index >= than.
index);
1606 void refresh_state();
1620 template <
typename T>
1623 friend typename const_iterator::container_t;
1645 return (*const_iterator::cont)[const_iterator::index + offset];
1675 reference
operator*()
const {
return reference(const_iterator::operator*()); }
1694 template <
typename BITER,
typename EITER>
1702 auto const&
end()
const {
return e; }
1707 template <
typename T>
1714 template <
typename T>
1741 template <
typename T>
1744 template <
typename T>
1751 template <
typename T>
1754 if (new_size >=
size()) {
1755 nominal_size = new_size;
1764 if (new_size == iLastRange->begin_index())
1765 ranges.erase(iLastRange);
1766 else if (new_size < iLastRange->end_index())
1767 iLastRange->resize(new_size - iLastRange->begin_index());
1771 nominal_size = new_size;
1774 template <
typename T>
1777 if (new_size ==
size())
return;
1778 if (new_size >
size()) {
1783 ranges.back().resize(new_size -
ranges.back().begin_index(), def_value);
1785 nominal_size = new_size;
1792 template <
typename T>
1798 template <
typename T>
1804 template <
typename T>
1810 template <
typename T>
1816 template <
typename T>
1824 if (iNextRange ==
ranges.begin())
return value_zero;
1830 return (index < range.
end_index()) ? range[index] : value_zero;
1833 template <
typename T>
1850 template <
typename T>
1853 if (
ranges.empty() || (index >=
size()))
throw std::out_of_range(
"empty sparse vector");
1856 return ((iNextRange ==
ranges.begin()) || ((--iNextRange)->end_index() <= index));
1859 template <
typename T>
1862 return std::accumulate(begin_range(),
1868 template <
typename T>
1877 if (iNextRange !=
ranges.begin()) {
1883 if (index < range.
end_index())
return range[index] = value;
1886 return const_cast<datarange_t&
>(add_range(index, {value}))[index];
1889 template <
typename T>
1897 if (iNextRange ==
ranges.begin())
return;
1906 if (range.
size() == 1)
ranges.erase(iNextRange);
1910 else if (index == range.
end_index() - 1)
1924 template <
typename T>
1931 template <
typename T>
1938 template <
typename T>
1942 if (
ranges.empty())
throw std::out_of_range(
"empty sparse vector");
1945 return ((iNextRange ==
ranges.begin()) || (index >= (--iNextRange)->end_index())) ?
ranges.end() :
1949 template <
typename T>
1953 if (
ranges.empty())
throw std::out_of_range(
"empty sparse vector");
1956 if (iNextRange ==
ranges.end())
throw std::out_of_range(
"index in no range of the sparse vector");
1960 template <
typename T>
1964 return const_cast<datarange_t&
>(
const_cast<const this_t*
>(
this)->find_range(index));
1967 template <
typename T>
1970 if (
ranges.empty() || (index >=
size()))
throw std::out_of_range(
"empty sparse vector");
1973 if ((iNextRange ==
ranges.begin()) || ((--iNextRange)->end_index() <= index)) {
return {}; }
1974 return void_range(iNextRange);
1977 template <
typename T>
1978 template <
typename ITER>
1986 if ((iInsert !=
ranges.begin()) && std::prev(iInsert)->borders(offset)) {
1988 (--iInsert)->extend(offset, first, last);
1993 iInsert = insert_range(iInsert, {offset, first, last});
1995 return merge_ranges(iInsert);
1998 template <
typename T>
2004 return add_range_before(
2006 std::move(new_data),
2007 std::upper_bound(
ranges.begin(),
2010 typename datarange_t::less_int_range(datarange_t::less)));
2014 template <
typename T>
2015 template <
typename ITER,
typename OP>
2037 auto const insertionPoint = offset;
2038 auto destRange = find_range_iter_at_or_after(offset);
2039 while (src != last) {
2045 if ((destRange != end_range()) && destRange->includes(offset)) {
2047 auto dest = destRange->get_iterator(offset);
2049 auto const end = destRange->end();
2050 while (src != last) {
2051 *dest = op(*dest, *src);
2054 if (++dest ==
end)
break;
2056 if (src == last)
break;
2057 offset = destRange->end_index();
2070 (destRange == end_range()) ? std::distance(src, last) : (destRange->begin_index() - offset);
2074 combinedData.reserve(newRangeSize);
2076 while (i++ < newRangeSize) {
2077 combinedData.push_back(op(void_value, *src));
2078 if (++src == last)
break;
2082 destRange = insert_range(destRange, {offset, std::move(combinedData)});
2087 offset = destRange->end_index();
2097 return merge_ranges(find_extending_range_iter(insertionPoint == 0 ? 0 : insertionPoint - 1));
2101 template <
typename T>
2107 if ((first.
cont !=
this) || (last.
cont !=
this)) {
2108 throw std::runtime_error(
"lar::sparse_vector::make_void(): iterators from alien container");
2111 if (first >= last)
return;
2118 if (first_range ==
ranges.end())
return;
2121 if (first.
index > first_range->begin_index()) {
2122 if (first_range == last_range) {
2126 last_range =
ranges.emplace(++last_range,
2128 first_range->begin() + first_range->relative_index(last.
index),
2129 first_range->end());
2131 first_range->move_tail(first.
index);
2134 first_range->move_tail(first.
index);
2140 if ((last_range !=
ranges.end()) && (last.
index > last_range->begin_index()))
2141 eat_range_head(last_range, last.
index);
2144 ranges.erase(first_range, last_range);
2147 template <
typename T>
2150 auto r{std::move(*iRange)};
2155 template <
typename T>
2159 if (
ranges.empty())
return true;
2162 while (iNext != rend) {
2164 if (iRange->empty())
return false;
2165 if (iNext != rend) {
2166 if (!(*iRange < *iNext))
return false;
2167 if (!iRange->separate(*iNext))
return false;
2170 if (nominal_size <
ranges.back().end_index())
return false;
2176 template <
typename T>
2182 return std::upper_bound(
2183 rbegin,
ranges.end(), index,
typename datarange_t::less_int_range(datarange_t::less));
2186 template <
typename T>
2192 return std::upper_bound(
2193 rbegin,
ranges.end(), index,
typename datarange_t::less_int_range(datarange_t::less));
2196 template <
typename T>
2201 auto after = find_next_range_iter(index);
2203 return ((after !=
ranges.begin()) && (index < std::prev(after)->end_index())) ? std::prev(after) :
2207 template <
typename T>
2212 auto after = find_next_range_iter(index);
2214 return ((after !=
ranges.begin()) && (index < std::prev(after)->end_index())) ? std::prev(after) :
2218 template <
typename T>
2224 auto it = find_next_range_iter(index, rbegin);
2227 return ((it != rbegin) && std::prev(it)->borders(index)) ? std::prev(it) : it;
2230 template <
typename T>
2235 auto it = find_next_range_iter(index, rbegin);
2238 return ((it != rbegin) && std::prev(it)->borders(index)) ? std::prev(it) : it;
2241 template <
typename T>
2251 if ((iInsert !=
ranges.begin()) && (iInsert - 1)->borders(offset)) {
2253 (--iInsert)->extend(offset, new_data.begin(), new_data.end());
2261 iInsert = insert_range(iInsert, {offset, std::move(new_data)});
2263 return merge_ranges(iInsert);
2266 template <
typename T>
2271 while (iNext !=
ranges.end()) {
2272 if (!iRange->borders(iNext->begin_index()))
break;
2275 if (iNext->end_index() > iRange->end_index()) {
2276 iRange->
extend(iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
2278 iNext =
ranges.erase(iNext);
2284 template <
typename T>
2289 if (index <= iRange->begin_index())
return iRange;
2290 if (index >= iRange->end_index())
return ranges.erase(iRange);
2291 iRange->move_head(index);
2295 template <
typename T>
2298 if (!
ranges.empty()) nominal_size = std::max(nominal_size,
ranges.back().end_index());
2299 return nominal_size;
2304 template <
typename T>
2313 template <
typename T>
2323 template <
typename T>
2329 return expected_vector_size(a.
size() + b.
size() + gap_size) <=
2330 expected_vector_size(a.
size()) + expected_vector_size(b.
size());
2334 template <
typename T>
2335 std::ostream& operator<<(std::ostream& out, const lar::sparse_vector<T>& v)
2338 out <<
"Sparse vector of size " << v.size() <<
" with " << v.get_ranges().size() <<
" ranges:";
2340 rend = v.end_range();
2341 while (iRange != rend) {
2353 return out << std::endl;
2359 template <
typename T>
2360 template <
typename ITER>
2365 std::max(base_t::relative_index(index) + std::distance(first, last),
base_t::size());
2366 base_t::resize(new_size);
2368 std::copy(first, last, get_iterator(index));
2372 template <
typename T>
2377 if (delta == 0)
return;
2378 base_t::move_head(delta);
2388 template <
typename T>
2389 template <
typename Stream>
2392 out <<
"[" << this->begin_index() <<
" - " << this->end_index() <<
"] (" << this->
size()
2394 for (
auto const& v : this->
values)
2402 template <
typename T>
2407 if (!cont || (index >= cont->size()))
return *
this;
2413 if (currentRange != cont->ranges.end()) {
2415 if (currentRange->end_index() <= index) ++currentRange;
2421 template <
typename T>
2426 if (!cont)
throw std::out_of_range(
"iterator to no sparse vector");
2429 if (index >= cont->size())
return value_zero;
2432 if (currentRange == cont->ranges.end())
return value_zero;
2435 if (index < currentRange->begin_index())
return value_zero;
2437 return (*currentRange)[index];
2440 template <
typename T>
2444 if (delta == 1)
return this->operator++();
2446 if ((currentRange == cont->ranges.end()) || !currentRange->includes(index)) refresh_state();
2450 template <
typename T>
2457 template <
typename T>
2461 if ((currentRange == cont->ranges.end()) || !currentRange->includes(index + delta))
2464 iter.
index += delta;
2468 template <
typename T>
2476 template <
typename T>
2480 if (cont != iter.
cont) {
2481 throw std::runtime_error(
"lar::sparse_vector::const_iterator:" 2482 " difference with alien iterator");
2484 return index - iter.
index;
2487 template <
typename T>
2494 currentRange = cont->find_next_range_iter(index);
2496 if (currentRange != cont->ranges.begin()) {
2497 if ((currentRange - 1)->end_index() > index) --currentRange;
2512 #endif // LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H bool operator>(const const_iterator &than) const
Iterator comparisons.
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
Comparison operators: determined by the position pointed by the iterators.
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)
const datarange_t & add_range(size_type offset, const CONT &new_data)
Copies the elements in container to a range with specified offset.
bool operator>=(const const_iterator &than) const
Iterator comparisons.
iterator operator-(difference_type delta) const
Increment and decrement operators.
Iterator to the sparse vector values.
vector_t::const_pointer const_pointer
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
Comparison operators: determined by the position pointed by the iterators.
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.
reference operator[](size_type offset) const
Random access.
void dump(Stream &&out) const
Dumps the content of this data range into a stream.
bool operator<=(const const_iterator &than) const
Iterator comparisons.
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.
std::ptrdiff_t difference_type
constexpr bool operator<(CryostatID const &a, CryostatID const &b)
Order cryostats with increasing ID.
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.
bool operator<(const const_iterator &than) const
Iterator comparisons.
constexpr auto abs(T v)
Returns the absolute value of the argument.
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.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
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
Returns an iterator to the range no earlier than index, or end() if none.
value_type & operator=(value_type v)
const_iterator cend() const
Standard iterators interface.
range_const_iterator find_next_range_iter(size_type index) const
Returns an iterator to the range after index.
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)
Turns the specified range into void.
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)
T value_type
type of the stored values
bool is_void(size_type index) const
Returns whether the specified position is void.
bool separate(const range_t &r) const
Returns if there are elements in between this and the specified range.
auto iterate_ranges() -> decltype(auto)
Returns the internal list of non-void ranges.
const_iterator get_iterator(size_type index) const
Returns an iterator to the specified absolute value (no check!)
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
std::random_access_iterator_tag iterator_category
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.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
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.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
void move_tail(difference_type shift)
Moves the end of the range by the specified amount.
const_iterator cbegin() const
begin and end iterators
bool operator<(const this_t &as) const
Comparison operators: determined by the position pointed by the iterators.
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
Comparison operators: determined by the position pointed by the iterators.
const_iterator cend() const
begin and end iterators
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)
range_iterator find_next_range_iter(size_type index)
Returns an iterator to the range after index.
constexpr bool is_valid(IDNumber_t< L > const id) noexcept
sparse_vector & operator=(sparse_vector &&from)
Move assignment.
Namespace for special initialization.
datarange_t()
Default constructor: an empty range.
const_iterator get_const_iterator(size_type index) const
Returns an iterator to the specified absolute value (no check!)
iterator end()
Standard iterators interface.
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
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
void assign(const CONT &new_data)
Copies data from a container.
const_iterator operator-(difference_type delta) const
Increment and decrement operators.
this_t & operator++()
Increments the position of the iterator, returns the new position.
value_const_iterator()
Default constructor: use the default value.
typename sparse_vector< T >::range_iterator base_iterator
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
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.
const vector_t & data() const
Return the vector of data values (only constant access).
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
bool optimize(size_t)
Performs internal optimization, returns whether the object was changed.
range_list_t::const_iterator range_const_iterator
type of constant iterator over ranges
const_iterator operator++(int)
Increment and decrement operators.
const_iterator & operator-=(difference_type delta)
Increment and decrement operators.
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 _)
Increment and decrement operators.
difference_type index
(arbitrary) position pointed by the iterator
const_iterator()
Default constructor, does not iterate anywhere.
Collection of utilities for dumping data on screen.
void resize(size_t new_size, value_type def_value)
Resizes the range (optionally filling the new elements with def_value)
this_t operator+(difference_type ofs) const
Returns an iterator pointing ahead of this one by the specified steps.
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_type operator[](size_type index) const
Access to an element (read only)
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.
const value_type & operator[](size_type index) const
Returns the value at the specified absolute index.
static bool less(const range_t &a, size_type b)
Returns if a is "less" than b.
static bool less(size_type a, const range_t &b)
Returns if a is "less" than 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
LArSoft-specific namespace.
size_type nominal_size
current size
iterator operator+(difference_type delta) const
Increment and decrement operators.
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
Namespace hiding implementation details.
range_iterator find_range_iterator(size_type index)
Returns an iterator to the range containing the specified index.
bool empty() const
Returns whether the vector is empty.
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
Returns the internal list of non-void ranges.
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
begin and end iterators
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)
Plug a new data range in the specified position; no check performed.
datarange_t const & base() const
std::forward_iterator_tag iterator_category
range_const_iterator end_range() const
Returns a constant iterator to after the last data range.
iterator & operator-=(difference_type delta)
Increment and decrement operators.
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.
const_reference operator[](size_type offset) const
Random access.
range_list_t::iterator range_iterator
type of iterator over ranges
const_iterator begin() const
begin and end iterators
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.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
container_t::value_type value_type
const_iterator cbegin() const
Standard iterators interface.
iterator begin()
begin and end iterators
iterator end()
begin and end iterators
const_iterator::reference reference
bool operator!=(const const_iterator &as) const
Iterator comparisons.
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
Comparison operators: determined by the position pointed by the iterators.
const_iterator operator+(difference_type delta) const
Increment and decrement operators.
datarange_t void_range(range_iterator const iRange)
Turns the specified range into void.
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
difference_type operator-(const this_t &iter) const
Returns the distance between this iterator and the other.
bool operator==(const range_t &as) const
Returns whether the specified range has our same offset and size.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
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.