LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
sparse_vector.h
Go to the documentation of this file.
1 
11 #ifndef LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
12 #define LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
13 
14 
15 // C/C++ standard library
16 #include <cstddef> // std::ptrdiff_t
17 #include <stdexcept> // std::out_of_range()
18 #include <vector>
19 #include <ostream>
20 #include <iterator> // std::distance()
21 #include <algorithm> // std::lower_bound(), std::max()
22 #include <numeric> // std::accumulate
23 
24 # include <type_traits> // std::is_integral
25 
26 
28 namespace lar {
29 
30 // -----------------------------------------------------------------------------
31 // --- utility classes for sparse_vector
32 // ---
33 
42 template <typename T>
45  public:
46  typedef T value_type;
47 
50 
52  explicit const_value_box(value_type new_value): value(new_value) {}
53 
55  this_t& operator= (value_type) { return *this; }
56 
58  operator value_type() const { return value; }
60  operator const value_type& () const { return value; }
62 
63  protected:
64  value_type value;
65 }; // class const_value_box
66 
67 
70 template <typename T>
72  public std::iterator<std::random_access_iterator_tag, T>
73 {
74  typedef std::iterator<std::random_access_iterator_tag, T> base_t;
76 
77  public:
78 
79  using typename base_t::value_type;
80  using typename base_t::difference_type;
81 
84 
86  value_const_iterator(value_type new_value): value(new_value) {}
87 
89  value_const_iterator(value_type new_value, difference_type offset):
90  index(offset), value(new_value) {}
91 
93  value_type operator* () const { return value; }
94 
96  value_type operator[] (difference_type) const { return value; }
97 
99  this_t& operator++() { ++index; return *this; }
100 
102  this_t operator++(int) { this_t copy(*this); ++index; return copy; }
103 
105  this_t& operator--() { --index; return *this; }
106 
108  this_t operator--(int) { this_t copy(*this); --index; return copy; }
109 
111  this_t& operator+= (difference_type ofs) { index += ofs; return *this; }
112 
114  this_t& operator-= (difference_type ofs) { index -= ofs; return *this; }
115 
117  this_t operator+ (difference_type ofs) const
118  { return this_t(value, index + ofs); }
119 
121  this_t operator- (difference_type ofs) const
122  { return this_t(value, index - ofs); }
123 
126  difference_type operator- (const this_t& iter) const
127  { return index - iter.index; }
128 
130  bool operator== (const this_t& as) const { return index == as.index; }
132  bool operator!= (const this_t& as) const { return index != as.index; }
133 
134  bool operator< (const this_t& as) const { return index < as.index; }
135  bool operator<= (const this_t& as) const { return index <= as.index; }
136  bool operator> (const this_t& as) const { return index > as.index; }
137  bool operator>= (const this_t& as) const { return index >= as.index; }
139 
140  protected:
141  difference_type index{0};
143 }; // class value_const_iterator<>
144 
145 
151 template <typename T>
155 )
156  { return { iter.value, iter.index + ofs }; }
157 
158 /* // not ready yet...
159 template <typename T>
160 class value_iterator: public value_const_iterator<T> {
161  using base_t = value_const_iterator<T>;
162  using this_t = value_iterator<T>;
163  using const_value_box<value_type> = value_box;
164  public:
165 
166  using typename base_t::value_type;
167  using typename base_t::reference;
168 
169  value_box operator* () const { return value_box(value); }
170  value_box operator[] (difference_type) const { return value_box(value); }
171 
172 }; // class value_iterator<>
173 */
174 
175 
176 
177 //------------------------------------------------------------------------------
178 //--- lar::range_t<SIZE>
179 //---
186 template <typename SIZE>
187 class range_t {
188  public:
189  typedef SIZE size_type;
190  typedef std::ptrdiff_t difference_type;
191 
192  static_assert
193  (std::is_integral<size_type>::value, "range_t needs an integral type");
194 
195  size_type offset;
196  size_type last;
197 
199  range_t(): offset(0), last(0) {}
200 
202  range_t(size_type from, size_type to):
203  offset(from), last(std::max(from, to)) {}
204 
205 
207  void set(size_type from, size_type to)
208  { offset = from; last = std::max(from, to); }
209 
211  size_type begin_index() const { return offset; }
212 
214  size_type end_index() const { return last; }
215 
217  size_type relative_index(size_type index) const { return index - offset; }
218 
220  size_type size() const { return last - offset; }
221 
223  void resize(size_type new_size) { last = offset + new_size; }
224 
226  void move_head(difference_type shift) { offset += shift; }
227 
229  void move_tail(difference_type shift) { last += shift; }
230 
232  bool empty() const { return last <= offset; }
233 
235  bool includes(size_type index) const
236  { return (index >= offset) && (index < last); }
237 
239  bool includes(const range_t& r) const
240  { return includes(r.begin_index()) && includes(r.end_index()); }
241 
243  bool overlap(const range_t& r) const
244  { return (begin_index() < r.end_index()) && (end_index() > r.begin_index()); }
245 
247  bool separate(const range_t& r) const
248  { return (begin_index() > r.end_index()) || (end_index() < r.begin_index()); }
249 
254  bool borders(size_type index) const
255  { return (index >= offset) && (index <= last); }
256 
258  bool operator< (const range_t& than) const { return less(*this, than); }
261 
263  bool operator== (const range_t& as) const
264  { return (offset == as.offset) && (last == as.last); }
265 
267  bool is_valid() const { return last >= offset; }
268 
270  static bool less(const range_t& a, const range_t& b)
272  { return a.offset < b.offset; }
273  static bool less(const range_t& a, size_type b)
274  { return a.offset < b; }
275  static bool less(size_type a, const range_t& b)
276  { return a < b.offset; }
278 
280  typedef bool (*less_int_range)(size_type, const range_t& b);
281 }; // class range_t
282 
283 
284 
285 // -----------------------------------------------------------------------------
286 // --- lar::sparse_vector<T>
287 // ---
288 
457 template <typename T>
460  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
461  // - - - public interface
462  public:
463  // - - - types
464  typedef T value_type;
465  typedef std::vector<value_type> vector_t;
467  typedef typename vector_t::size_type size_type;
468  typedef typename vector_t::difference_type difference_type;
470  typedef typename vector_t::pointer pointer;
471  typedef typename vector_t::const_pointer const_pointer;
472 // typedef typename vector_t::reference reference;
473 // typedef typename vector_t::const_reference const_reference;
474 
475  // --- declarations only ---
476  class reference;
477  class const_reference;
478  class iterator;
479  class const_iterator;
480 
481  class datarange_t;
482  // --- ----------------- ---
483 
484  typedef std::vector<datarange_t> range_list_t;
490 
491 
492  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
493  // - - - public methods
495  sparse_vector(): nominal_size(0), ranges() {}
496 
497 
499  sparse_vector(size_type new_size): nominal_size(0), ranges()
500  { resize(new_size); }
501 
507  sparse_vector(const vector_t& from, size_type offset = 0):
508  nominal_size(0), ranges()
509  { add_range(offset, from.begin(), from.end()); }
510 
512  sparse_vector(sparse_vector const&) = default;
513 
516  : nominal_size(from.nominal_size)
517  , ranges(std::move(from.ranges))
518  { from.nominal_size = 0; }
519 
521  sparse_vector& operator=(sparse_vector const&) = default;
522 
525  {
526  ranges = std::move(from.ranges);
527  nominal_size = from.nominal_size;
528  from.nominal_size = 0;
529  return *this;
530  } // operator= (sparse_vector&&)
531 
537  sparse_vector(vector_t&& from, size_type offset = 0):
538  nominal_size(0), ranges()
539  { add_range(offset, std::move(from)); }
540 
541 
543  ~sparse_vector() = default;
544 
545 
546  // - - - STL-like interface
548  void clear() { ranges.clear(); nominal_size = 0; }
549 
550 
552  size_type size() const { return nominal_size; }
553 
555  bool empty() const { return size() == 0; }
556 
558  size_type capacity() const { return nominal_size; }
559 
561  void resize(size_type new_size);
564  void resize(size_type new_size, value_type def_value);
566 
568  iterator begin();
570  iterator end();
571  const_iterator begin() const;
572  const_iterator end() const;
573  const_iterator cbegin() const { return begin(); }
574  const_iterator cend() const { return end(); }
576 
578  value_type operator[] (size_type index) const;
579 
581  reference operator[] (size_type index);
582 
583 
584  // - - - special interface
585 
589 
590  // --- element test
597  bool is_void(size_type index) const;
598 
599 
602  bool back_is_void() const
603  { return ranges.empty() || (ranges.back().end_index() < size()); }
604 
605 
607  size_type count() const;
609 
610 
614 
624  value_type& set_at(size_type index, value_type value);
625 
627  void unset_at(size_type index);
628 
630  void push_back(value_type value) { resize(size() + 1, value); }
633 
641  void push_back(value_type value, value_type thr)
642  {
643  if (is_zero(value, thr)) resize(size() + 1);
644  else push_back(value);
645  } // push_back()
647 
648 
650 
658  template <typename ITER>
659  void assign(ITER first, ITER last) { clear(); append(first, last); }
660 
668  template <typename CONT>
669  void assign(const CONT& new_data) { clear(); append(new_data); }
670 
677  void assign(vector_t&& new_data) { clear(); append(std::move(new_data)); }
679 
681 
682 
687 
688  // --- range location
689 
691  const range_list_t& get_ranges() const { return ranges; }
692 
694  size_type n_ranges() const { return ranges.size(); }
695 
697  const datarange_t& range(size_t i) const { return ranges[i]; }
698 
700  range_const_iterator begin_range() const { return ranges.begin(); }
701 
703  range_const_iterator end_range() const { return ranges.end(); }
704 
705 
707 
714  range_const_iterator find_range_iterator(size_type index) const;
715  range_iterator find_range_iterator(size_type index);
717 
719 
726  const datarange_t& find_range(size_type index) const;
727  datarange_t& find_range(size_type index);
729 
736  void make_void_around(size_type index);
737 
739 
752  template <typename ITER>
753  const datarange_t& add_range(size_type offset, ITER first, ITER last);
754 
767  template <typename CONT>
768  const datarange_t& add_range(size_type offset, const CONT& new_data)
769  { return add_range(offset, new_data.begin(), new_data.end()); }
770 
784  const datarange_t& add_range(size_type offset, vector_t&& new_data);
786 
788 
798  template <typename ITER>
799  const datarange_t& append(ITER first, ITER last)
800  { return add_range(size(), first, last); }
801 
811  template <typename CONT>
812  const datarange_t& append(const CONT& range_data)
813  { return add_range(size(), range_data); }
814 
825  const datarange_t& append(vector_t&& range_data)
826  { return add_range(size(), std::move(range_data)); }
828 
829 
831 
836  void void_range(range_iterator iRange) { ranges.erase(iRange); }
837  void void_range(size_t iRange) { ranges.erase(ranges.begin() + iRange); }
839 
841 
854  bool is_valid() const;
855 
856 
858  void make_void(iterator first, iterator last);
859 
860 
862  bool optimize() { return optimize(min_gap()); }
864  bool optimize(size_t) { return false; /* no optimization implemented yet */ }
866 
867 
869 
870  static constexpr value_type value_zero{0};
871 
873  static value_type abs(value_type v) { return (v < value_zero)? -v: v; }
874 
876  static value_type is_zero(value_type v) { return v == value_zero; }
877 
879  static value_type is_zero(value_type v, value_type thr)
880  { return abs(v - value_zero) <= thr; }
881 
883  static value_type is_equal(value_type a, value_type b)
884  { return is_zero(abs(a - b)); }
885 
887  static value_type is_equal(value_type a, value_type b, value_type thr)
888  { return is_zero(abs(a - b), thr); }
890 
892 
894  static size_t expected_vector_size(size_t size);
895 
897  static size_t min_gap();
898 
900  static bool should_merge(
901  const typename datarange_t::base_t& a,
902  const typename datarange_t::base_t& b
903  );
905 
906  // --------------------------------------------------------------------------
907  protected:
908 
909  size_type nominal_size;
910  range_list_t ranges;
911 
913 
919  range_iterator find_next_range_iter(size_type index)
920  { return find_next_range_iter(index, ranges.begin()); }
921  range_const_iterator find_next_range_iter(size_type index) const
922  { return find_next_range_iter(index, ranges.begin()); }
924 
925 
932  range_iterator find_next_range_iter(size_type index, range_iterator rbegin);
933  range_const_iterator find_next_range_iter
934  (size_type index, range_const_iterator rbegin) const;
936 
938  size_type minimum_size() const
939  { return ranges.empty()? 0: ranges.back().end_index(); }
940 
942  range_iterator insert_range(range_iterator iInsert, const datarange_t& data)
944  { return data.empty()? iInsert: ranges.insert(iInsert, data); }
945  range_iterator insert_range(range_iterator iInsert, datarange_t&& data)
946  { return data.empty()? iInsert: ranges.insert(iInsert, std::move(data)); }
948 
950  range_iterator eat_range_head(range_iterator iRange, size_t index);
951 
953  datarange_t& merge_ranges(range_iterator iRange);
954 
956  size_type fix_size();
957 
958 }; // class sparse_vector<>
959 
960 
961 } // namespace lar
962 
978 template <typename T>
979 std::ostream& operator<< (std::ostream& out, const lar::sparse_vector<T>& v);
980 
981 
982 
983 // -----------------------------------------------------------------------------
984 // --- sparse_vector::datarange_t definition
985 // ---
986 
988 template <typename T>
989 class lar::sparse_vector<T>::datarange_t: public range_t<size_type> {
990  public:
992 
993  typedef typename vector_t::iterator iterator;
995 
997  datarange_t(): base_t(), values() {}
998 
1000  datarange_t(const base_t& range): base_t(range), values(range.size()) {}
1001 
1003  template <typename ITER>
1004  datarange_t(size_type offset, ITER first, ITER last):
1005  base_t(offset, offset + std::distance(first, last)),
1006  values(first, last)
1007  {}
1008 
1010  datarange_t(size_type offset, vector_t&& data):
1011  base_t(offset, offset + data.size()), values(data)
1012  {}
1013 
1014 
1016  iterator get_iterator(size_type index)
1018  { return values.begin() + index - base_t::begin_index(); }
1019  const_iterator get_iterator(size_type index) const
1020  { return values.begin() + index - base_t::begin_index(); }
1022 
1024  iterator begin() { return values.begin(); }
1026  iterator end() { return values.end(); }
1027  const_iterator begin() const { return values.begin(); }
1028  const_iterator end() const { return values.end(); }
1029  const_iterator cbegin() const { return values.cbegin(); }
1030  const_iterator cend() const { return values.cend(); }
1032 
1034  void resize(size_t new_size)
1036  { values.resize(new_size); fit_size_from_data(); }
1037  void resize(size_t new_size, value_type def_value)
1038  { values.resize(new_size, def_value); fit_size_from_data(); }
1040 
1042  value_type& operator[] (size_type index)
1044  { return values[base_t::relative_index(index)]; }
1045  const value_type& operator[] (size_type index) const
1046  { return values[base_t::relative_index(index)]; }
1048 
1050  const vector_t& data() const { return values; }
1052 // vector_t& data() { return values; }
1054 
1059  template <typename ITER>
1060  datarange_t& extend(size_type index, ITER first, ITER last);
1061 
1062 
1068  void move_head(size_type to_index, value_type def_value = value_zero);
1069 
1075  void move_tail(size_type to_index, value_type def_value = value_zero)
1076  { resize(base_t::relative_index(to_index), def_value); }
1077 
1078 
1079  protected:
1081 
1082  void fit_size_from_data() { base_t::resize(values.size()); }
1083 
1084 }; // class datarange_t
1085 
1086 
1087 
1088 // -----------------------------------------------------------------------------
1089 // --- sparse_vector iterators definition
1090 // ---
1091 
1093 template <typename T>
1095  protected:
1096  const value_type* ptr;
1097  public:
1098  const_reference(const value_type* pValue = 0): ptr(pValue) {}
1100 
1101  explicit operator value_type() const { return ptr? *ptr: value_zero; }
1102  operator const value_type&() const
1103  { return ptr? *ptr: value_zero; }
1104 }; // lar::sparse_vector<T>::const_reference
1105 
1106 
1114 template <typename T>
1116  friend class iterator;
1117 
1118  // This object "disappears" when assigned to: either the assignment is not
1119  // possible, and then a segmentation fault will occur, or the return value
1120  // is an actual C++ reference to the assigned value.
1121  // The same is true when explicitly converting it to a reference.
1122  public:
1123  reference(value_type* pValue = 0): const_reference(pValue) {}
1125 
1126  reference& operator=(const reference&) = default;
1128  { return const_cast<value_type&>(*const_reference::ptr) = v; }
1129 
1130  operator const_reference() const
1131  { return const_reference(const_reference::ptr); }
1132  explicit operator value_type&()
1133  { return const_cast<value_type&>(*const_reference::ptr); }
1134 
1135  protected:
1136  explicit reference(const const_reference& from): const_reference(from) {}
1137 
1138 }; // lar::sparse_vector<T>::reference
1139 
1140 
1141 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1143 template <typename T>
1145  //
1146  // This iterator fulfils the traits of an immutable forward iterator.
1147  //
1148 
1149  protected:
1150  friend class container_t;
1151 
1155 
1156 
1157  public:
1158  // so far, only forward interface is implemented;
1159  // backward is tricky...
1160  typedef std::forward_iterator_tag iterator_category;
1161 
1163  struct special {
1164  class begin {};
1165  class end {};
1166  };
1167 
1168  // types
1171  typedef typename container_t::pointer pointer;
1173  // note that this is not out little box, it's the normal C++ constant
1174  // reference from the underlying vector
1175  typedef typename vector_t::const_reference const_reference;
1176 
1177 
1179  const_iterator(): cont(nullptr), index(0), currentRange() {}
1180 
1182  const_iterator(const container_t& c, size_type offset):
1183  cont(&c), index(std::min(offset, c.size())), currentRange()
1184  { refresh_state(); }
1185 
1187  const_iterator(const container_t& c, const typename special::begin):
1188  cont(&c), index(0), currentRange(c.get_ranges().begin())
1189  {}
1190 
1192  const_iterator(const container_t& c, const typename special::end):
1193  cont(&c), index(c.size()), currentRange(c.get_ranges().end())
1194  {}
1195 
1197  const_reference operator[] (size_type offset) const
1198  { return (*cont)[index + offset]; }
1199 
1201  const_reference operator*() const;
1202 
1204  const_iterator& operator++();
1207  { const_iterator copy(*this); const_iterator::operator++(); return copy; }
1209 
1210 
1212  const_iterator& operator+= (difference_type delta);
1214  const_iterator& operator-= (difference_type delta);
1215  const_iterator operator+ (difference_type delta) const;
1216  const_iterator operator- (difference_type delta) const;
1218 
1220  difference_type operator- (const const_iterator& iter) const;
1221 
1223  bool operator== (const const_iterator& as) const
1225  { return (cont == as.cont) && (index == as.index); }
1226  bool operator!= (const const_iterator& as) const
1227  { return (cont != as.cont) || (index != as.index); }
1228  bool operator< (const const_iterator& than) const
1229  { return (cont == than.cont) && (index < than.index); }
1230  bool operator> (const const_iterator& than) const
1231  { return (cont == than.cont) && (index > than.index); }
1232  bool operator<= (const const_iterator& than) const
1233  { return (cont == than.cont) && (index <= than.index); }
1234  bool operator>= (const const_iterator& than) const
1235  { return (cont == than.cont) && (index >= than.index); }
1237 
1239  range_const_iterator get_current_range() const { return currentRange; }
1240 
1241  protected:
1242  //
1243  // Logic of the internals:
1244  // - cont provides the list of ranges
1245  // - index is the absolute index in the container
1246  // - currentRange is a pointer to the "current" range, cached for speed
1247  //
1248  // An iterator past-the-end has the index equal to the size of the
1249  // container it points to. Operations on it are undefined, except that
1250  // going backward by one decrement goes back to the container
1251  // (if not empty) TODO currently backward iteration is not supported
1252  //
1253  // When the iterator is pointing to an element within a range,
1254  // currentRange points to that range.
1255  // When the iterator is pointing into the void of the vector, currentRange
1256  // points to the range next to that void area, or end() if there is none.
1257  // When the iterator is past-the-end, currentRange is not defined.
1258  //
1259  // Conversely, when the index is equal (or greater) to the size of the
1260  // container, the iterator is not dereferenciable, the iterator points
1261  // past-the-end of the container.
1262  // When currentRange points to a valid range and the index
1263  // is before that range, the iterator is pointing to the void.
1264  // When currentRange points to a valid range and the index
1265  // is inside that range, the iterator is pointing to an item in that
1266  // range.
1267  // When currentRange points to a valid range, the index can't point beyond
1268  // that range.
1269  // When currentRange points to the past-to-last range, the iterator is
1270  // pointing to the void (past the last range).
1271  //
1272  const container_t* cont;
1273  size_type index;
1274  ranges_const_iterator currentRange;
1275 
1277  void refresh_state();
1278 
1279 }; // class lar::sparse_vector<T>::const_iterator
1280 
1281 
1292 template <typename T>
1294  typedef typename const_iterator::container_t container_t;
1295  friend typename const_iterator::container_t;
1296 
1297  public:
1298  typedef typename const_iterator::reference reference;
1299  typedef typename const_iterator::const_reference const_reference;
1300  typedef typename const_iterator::special special;
1301 
1304 
1306  iterator(container_t& c, size_type offset = 0):
1307  const_iterator(c, offset) {}
1308 
1310  iterator(const container_t& c, const typename special::begin _):
1311  const_iterator(c, _) {}
1312 
1314  iterator(const container_t& c, const typename special::end _):
1315  const_iterator(c, _) {}
1316 
1318  reference operator[] (size_type offset) const
1319  { return (*const_iterator::cont)[const_iterator::index + offset]; }
1320 
1322  iterator& operator++() { const_iterator::operator++(); return *this; }
1326 
1330  { const_iterator::operator+=(delta); return *this; }
1331  iterator& operator-= (difference_type delta)
1332  { const_iterator::operator+=(delta); return *this; }
1334  { return const_iterator::operator+(delta); }
1336  { return const_iterator::operator-(delta); }
1338 
1339 
1341  reference operator*() const
1342  { return reference(const_iterator::operator*()); }
1343 
1344 // /// Returns the current range internal value; use it at your own risk!!
1345 // range_iterator get_current_range() const
1346 // { return const_iterator::currentRange; }
1347 
1348  protected:
1349 
1350  // also worth conversion
1352 
1353 }; // class lar::sparse_vector<T>::iterator
1354 
1355 
1356 
1357 // -----------------------------------------------------------------------------
1358 // --- implemetation ---------------------------------------------------------
1359 // -----------------------------------------------------------------------------
1360 
1361 //------------------------------------------------------------------------------
1362 //--- sparse_vector implementation
1363 
1364 template <typename T>
1365 constexpr typename lar::sparse_vector<T>::value_type
1367 
1368 
1369 template <typename T>
1371  if (new_size >= size()) {
1372  nominal_size = new_size;
1373  return;
1374  }
1375 
1376  // truncating...
1377  range_iterator iLastRange = find_next_range_iter(new_size);
1378  ranges.erase(iLastRange, ranges.end());
1379  if (!ranges.empty()) {
1380  range_iterator iLastRange = ranges.end() - 1;
1381  if (new_size == iLastRange->begin_index())
1382  ranges.erase(iLastRange);
1383  else if (new_size < iLastRange->end_index())
1384  iLastRange->resize(new_size - iLastRange->begin_index());
1385  } // if we have ranges
1386 
1387  // formally resize
1388  nominal_size = new_size;
1389 } // lar::sparse_vector<T>::resize()
1390 
1391 
1392 template <typename T>
1394  if (new_size == size()) return;
1395  if (new_size > size()) {
1396 
1397  if (back_is_void()) // add a new range
1398  append(vector_t(new_size - size(), def_value));
1399  else // extend the last range
1400  ranges.back().resize(new_size - ranges.back().begin_index(), def_value);
1401 
1402  nominal_size = new_size;
1403  return;
1404  }
1405  // truncating is the same whether there is a default value or not
1406  resize(new_size);
1407 } // lar::sparse_vector<T>::resize()
1408 
1409 
1410 template <typename T>
1412  { return iterator(*this, typename iterator::special::begin()); }
1413 
1414 template <typename T>
1416  { return iterator(*this, typename iterator::special::end()); }
1417 
1418 template <typename T>
1421  { return const_iterator(*this, typename const_iterator::special::begin()); }
1422 
1423 template <typename T>
1426  { return const_iterator(*this, typename const_iterator::special::end()); }
1427 
1428 template <typename T>
1430  (size_type index) const
1431 {
1432  // first range not including the index
1433  range_const_iterator iNextRange = find_next_range_iter(index);
1434 
1435  // if not even the first range includes the index, we are in the void
1436  // (or in some negative index space, if index signedness allowed);
1437  if (iNextRange == ranges.begin()) return value_zero;
1438 
1439  // otherwise, let's take the previous range;
1440  // if it includes the index, we return its value;
1441  // or it precedes it, and our index is in the void: return zero
1442  const datarange_t& range(*--iNextRange);
1443  return (index < range.end_index())? range[index]: value_zero;
1444 } // lar::sparse_vector<T>::operator[]
1445 
1446 
1447 template <typename T>
1449  (size_type index)
1450 {
1451  // first range not including the index
1452  range_iterator iNextRange = find_next_range_iter(index);
1453 
1454  // if not even the first range includes the index, we are in the void
1455  // (or in some negative index space, if index signedness allowed);
1456  if (iNextRange == ranges.begin()) return reference();
1457 
1458  // otherwise, let's take the previous range;
1459  // if it includes the index, we return its value;
1460  // or it precedes it, and our index is in the void: return zero
1461  datarange_t& range(*--iNextRange);
1462  return (index < range.end_index())? reference(range[index]): reference();
1463 } // lar::sparse_vector<T>::operator[]
1464 
1465 
1466 template <typename T>
1468  if (ranges.empty() || (index >= size()))
1469  throw std::out_of_range("empty sparse vector");
1470  // range after the index:
1471  range_const_iterator iNextRange = find_next_range_iter(index);
1472  return ((iNextRange == ranges.begin())
1473  || ((--iNextRange)->end_index() <= index));
1474 } // lar::sparse_vector<T>::is_void()
1475 
1476 
1477 template <typename T>
1479  const
1480 {
1481  return std::accumulate(begin_range(), end_range(), size_type(0),
1482  [](size_type s, const datarange_t& rng) { return s + rng.size(); }
1483  );
1484 } // count()
1485 
1486 
1487 template <typename T>
1490 {
1491  // first range not including the index
1492  range_iterator iNextRange = find_next_range_iter(index);
1493 
1494  // if not even the first range includes the index, we are in the void
1495  // (or in some negative index space, if index signedness allowed);
1496  if (iNextRange != ranges.begin()) {
1497  // otherwise, let's take the previous range;
1498  // if it includes the index, we set the existing value;
1499  // or it precedes it, and our index is in the void, add the value as a
1500  // range
1501  datarange_t& range(*--iNextRange);
1502  if (index < range.end_index()) return range[index] = value;
1503  }
1504  // so we are in the void; add the value as a new range
1505  return const_cast<datarange_t&>(add_range(index, { value }))[index];
1506 } // lar::sparse_vector<T>::set_at()
1507 
1508 
1509 template <typename T>
1511  // first range not including the index
1512  range_iterator iNextRange = find_next_range_iter(index);
1513 
1514  // if not even the first range includes the index, we are in the void
1515  // (or in some negative index space, if index signedness allowed);
1516  if (iNextRange == ranges.begin()) return;
1517 
1518  // otherwise, let's take the previous range;
1519  // or it precedes the index, and our index is in the void
1520  datarange_t& range(*--iNextRange);
1521  if (index >= range.end_index()) return; // void already
1522 
1523  // it includes the index:
1524  // - if it's a one-element range, remove the range
1525  if (range.size() == 1) ranges.erase(iNextRange);
1526  // - if it's on a border, resize the range
1527  else if (index == range.begin_index())
1528  range.move_head(index + 1);
1529  else if (index == range.end_index() - 1)
1530  range.move_tail(index);
1531  // - if it's inside, break the range in two
1532  else if (index < range.end_index()) {
1533  // we are going to put a hole in a range;
1534  // this effectively creates two ranges;
1535  // first create the rightmost range, and add it to the list
1536  ranges.emplace(++iNextRange, index + 1,
1537  range.begin() + range.relative_index(index + 1),
1538  range.end()
1539  );
1540  // then cut the existing one
1541  range.move_tail(index);
1542  }
1543 } // lar::sparse_vector<T>::unset_at()
1544 
1545 
1546 template <typename T>
1549 {
1550  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1551  // range after the index:
1552  range_const_iterator iNextRange = find_next_range_iter(index);
1553  return ((iNextRange == ranges.begin())
1554  || (index >= (--iNextRange)->end_index()))?
1555  ranges.end(): iNextRange;
1556 } // lar::sparse_vector<T>::find_range_iterator() const
1557 
1558 
1559 template <typename T>
1562 {
1563  return ranges.begin() + (
1564  (const_cast<const this_t*>(this)->find_range_iterator(index))
1565  - ranges.begin());
1566 } // lar::sparse_vector<T>::find_range_iterator()
1567 
1568 
1569 template <typename T>
1570 const typename lar::sparse_vector<T>::datarange_t&
1572 {
1573  if (ranges.empty()) throw std::out_of_range("empty sparse vector");
1574  // range on the index:
1575  range_const_iterator iNextRange = find_range_iterator(index);
1576  if (iNextRange == ranges.end())
1577  throw std::out_of_range("index in no range of the sparse vector");
1578  return *iNextRange;
1579 } // lar::sparse_vector<T>::find_range() const
1580 
1581 template <typename T>
1582 inline typename lar::sparse_vector<T>::datarange_t&
1584 {
1585  return const_cast<datarange_t&>
1586  (const_cast<const this_t*>(this)->find_range(index));
1587 } // lar::sparse_vector<T>::find_range()
1588 
1589 
1590 template <typename T>
1592  if (ranges.empty() || (index >= size()))
1593  throw std::out_of_range("empty sparse vector");
1594  // range after the index:
1595  range_iterator iNextRange = find_next_range_iter(index);
1596  if ((iNextRange == ranges.begin())
1597  || ((--iNextRange)->end_index() <= index))
1598  {
1599  return;
1600  }
1601  ranges.erase(iNextRange);
1602 } // lar::sparse_vector<T>::make_void_around()
1603 
1604 
1605 template <typename T> template <typename ITER>
1607  (size_type offset, ITER first, ITER last)
1608 {
1609  // insert the new range before the existing range which starts after offset
1610  range_iterator iInsert = std::upper_bound(
1611  ranges.begin(), ranges.end(), offset,
1612  typename datarange_t::less_int_range(datarange_t::less)
1613  );
1614 
1615  // is there a range before this, which includes the offset?
1616  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1617  // then we should extend it
1618  (--iInsert)->extend(offset, first, last);
1619  }
1620  else {
1621  // no range before the insertion one includes the offset of the new range;
1622  // ... we need to add it as a new range
1623  iInsert = insert_range(iInsert, { offset, first, last });
1624  }
1625  return merge_ranges(iInsert);
1626 } // lar::sparse_vector<T>::add_range<ITER>()
1627 
1628 
1629 template <typename T>
1631  (size_type offset, vector_t&& new_data)
1632 {
1633  // insert the new range before the existing range which starts after offset
1634  range_iterator iInsert = std::upper_bound(
1635  ranges.begin(), ranges.end(), offset,
1636  typename datarange_t::less_int_range(datarange_t::less)
1637  );
1638 
1639  // is there a range before this, which includes the offset?
1640  if ((iInsert != ranges.begin()) && (iInsert-1)->borders(offset)) {
1641  // then we should extend it
1642  (--iInsert)->extend(offset, new_data.begin(), new_data.end());
1643  }
1644  else {
1645  // no range before the insertion one includes the offset of the new range;
1646  // ... we need to add it as a new range;
1647  // it is not really clear to me [GP] why I need a std::move here, since
1648  // new_data is a rvalue already; in doubt, I have painted all this kind
1649  // of constructs with move()s, just in case
1650  iInsert = insert_range(iInsert, { offset, std::move(new_data) });
1651  }
1652  return merge_ranges(iInsert);
1653 } // lar::sparse_vector<T>::add_range(vector)
1654 
1655 
1656 template <typename T>
1658  // iterators have in "currentRange" either the range they point into,
1659  // or the range next to the void they point to
1660 
1661  if ((first.cont != this) || (last.cont != this)) {
1662  throw std::runtime_error
1663  ("lar::sparse_vector::make_void(): iterators from alien container");
1664  }
1665  // if first is after next, no range is identified
1666  if (first >= last) return;
1667 
1669  first_range
1670  = ranges.begin() + (first.get_current_range() - ranges.begin()),
1671  last_range = ranges.begin() + (last.get_current_range() - ranges.begin());
1672 
1673  //--- "first": void up to this iterator ---
1674  // if first in the last void region, there is nothing to erase
1675  if (first_range == ranges.end()) return;
1676 
1677  // if first is in the middle of a valid range instead, we have to resize it
1678  if (first.index > first_range->begin_index()) {
1679  if (first_range == last_range) {
1680  // we are going to erase a subset of a range;
1681  // this effectively creates two ranges;
1682  // first create the rightmost (last) range, and add it to the list
1683  last_range = ranges.emplace(++last_range, last.index,
1684  first_range->begin() + first_range->relative_index(last.index),
1685  first_range->end()
1686  );
1687  // then cut the existing one
1688  first_range->move_tail(first.index);
1689  return;
1690  }
1691  first_range->move_tail(first.index);
1692  ++first_range; // from next range on, start voiding
1693  }
1694 
1695  //--- "last"
1696  // if the index is inside a range, remove up to it
1697  if ((last_range != ranges.end()) && (last.index > last_range->begin_index()))
1698  eat_range_head(last_range, last.index);
1699 
1700  // finally, remove entirely the ranges in between
1701  ranges.erase(first_range, last_range);
1702 } // lar::sparse_vector<T>::make_void()
1703 
1704 
1705 template <typename T>
1707  // a sparse vector with no non-null elements can't be detected invalid
1708  if (ranges.empty()) return true;
1709 
1710  range_const_iterator iNext = ranges.begin(), rend = ranges.end();
1711  while (iNext != rend) {
1712  range_const_iterator iRange = iNext++;
1713  if (iRange->empty()) return false;
1714  if (iNext != rend) {
1715  if (!(*iRange < *iNext)) return false;
1716  if (!iRange->separate(*iNext)) return false;
1717  }
1718  } // while
1719  if (nominal_size < ranges.back().end_index()) return false;
1720  return true;
1721 } // lar::sparse_vector<T>::is_valid()
1722 
1723 
1724 
1725 // --- private methods
1726 
1727 template <typename T>
1730  (size_type index, range_iterator rbegin)
1731 {
1732  // this range has the offset (first index) above the index argument:
1733  return std::upper_bound(
1734  rbegin, ranges.end(), index,
1735  typename datarange_t::less_int_range(datarange_t::less)
1736  );
1737 } // lar::sparse_vector<T>::find_next_range_iter()
1738 
1739 template <typename T>
1742  (size_type index, range_const_iterator rbegin) const
1743 {
1744  // this range has the offset (first index) above the index argument:
1745  return std::upper_bound(
1746  rbegin, ranges.end(), index,
1747  typename datarange_t::less_int_range(datarange_t::less)
1748  );
1749 } // lar::sparse_vector<T>::find_next_range_iter() const
1750 
1751 
1752 template <typename T>
1755 {
1756  range_iterator iNext = iRange + 1;
1757  while (iNext != ranges.end()) {
1758  if (!iRange->borders(iNext->begin_index())) break;
1759  // iRange content dominates, but if iNext has data beyond it,
1760  // then we copy it
1761  if (iNext->end_index() > iRange->end_index()) {
1762  iRange->extend
1763  (iRange->end_index(), iNext->get_iterator(iRange->end_index()), iNext->end());
1764  }
1765  iNext = ranges.erase(iNext);
1766  } // while
1767  fix_size();
1768  return *iRange;
1769 } // lar::sparse_vector<T>::merge_ranges()
1770 
1771 
1772 template <typename T>
1774  (range_iterator iRange, size_t index)
1775 {
1776  if (index <= iRange->begin_index()) return iRange;
1777  if (index >= iRange->end_index()) return ranges.erase(iRange);
1778  iRange->move_head(index);
1779  return iRange;
1780 } // lar::sparse_vector<T>::eat_range_head()
1781 
1782 
1783 template <typename T>
1785  if (!ranges.empty())
1786  nominal_size = std::max(nominal_size, ranges.back().end_index());
1787  return nominal_size;
1788 } // lar::sparse_vector<T>::fix_size()
1789 
1790 
1791 // --- static methods
1792 
1793 template <typename T>
1795  // apparently, a chunk of heap memory takes at least 32 bytes;
1796  // that means that a vector of 1 or 5 32-bit integers takes the same
1797  // space; the overhead appears to be 8 bytes, which can be allocated
1798  return sizeof(vector_t)
1799  + std::max(size_t(32), (alignof(datarange_t)*size + 8));
1800 } // lar::sparse_vector<T>::expected_vector_size()
1801 
1802 
1803 template <typename T>
1805  // we assume here that there is no additional overhead by alignment;
1806  // the gap adds the space of another datarange_t, including the vector,
1807  // its data and overhead from heap (apparently, 8 bytes);
1808  //
1809  return (sizeof(datarange_t) + 8) / sizeof(value_type) + 1; // round up
1810 } // lar::sparse_vector<T>::min_gap()
1811 
1812 
1813 template <typename T>
1815  const typename datarange_t::base_t& a,
1816  const typename datarange_t::base_t& b
1817  )
1818 {
1819  size_type gap_size = (a < b)?
1820  b.begin_index() - a.begin_index() - a.size():
1821  a.begin_index() - b.begin_index() - b.size();
1822  return expected_vector_size(a.size() + b.size() + gap_size)
1823  <= expected_vector_size(a.size()) + expected_vector_size(b.size());
1824 } // lar::sparse_vector<T>::should_merge()
1825 
1826 
1827 
1828 // --- non-member functions
1829 template <typename T>
1830 std::ostream& operator<< (std::ostream& out, const lar::sparse_vector<T>& v) {
1831 
1832  out << "Sparse vector of size " << v.size() << " with "
1833  << v.get_ranges().size() << " ranges:";
1835  iRange = v.begin_range(), rend = v.end_range();
1836  while (iRange != rend) {
1837  out << "\n [" << iRange->begin_index() << " - " << iRange->end_index()
1838  << "] (" << iRange->size() << "):";
1840  iValue = iRange->begin(), vend = iRange->end();
1841  while (iValue != vend) out << " " << (*(iValue++));
1842  ++iRange;
1843  } // for
1844  return out << std::endl;
1845 } // operator<< (ostream, sparse_vector<T>)
1846 
1847 
1848 
1849 // -----------------------------------------------------------------------------
1850 // --- lar::sparse_vector<T>::datarange_t implementation
1851 // ---
1852 template <typename T> template <typename ITER>
1854  (size_type index, ITER first, ITER last)
1855 {
1856  size_type new_size = std::max(
1857  base_t::relative_index(index) + std::distance(first, last),
1858  base_t::size());
1859  base_t::resize(new_size);
1860  values.resize(new_size);
1861  std::copy(first, last, get_iterator(index));
1862  return *this;
1863 } // lar::sparse_vector<T>::datarange_t::extend()
1864 
1865 
1866 template <typename T>
1868  (size_type to_index, value_type def_value /* = value_zero */)
1869 {
1870  difference_type delta = to_index - base_t::begin_index();
1871  if (delta == 0) return;
1872  base_t::move_head(delta);
1873  if (delta > 0) // shrink
1874  values.erase(values.begin(), values.begin() + delta);
1875  else { // extend
1876  values.insert(values.begin(),
1878  value_const_iterator<value_type>(def_value) - delta
1879  );
1880  }
1881 } // lar::sparse_vector<T>::datarange_t::move_head()
1882 
1883 
1884 // -----------------------------------------------------------------------------
1885 // --- lar::sparse_vector<T>::const_iterator implementation
1886 // ---
1887 template <typename T>
1890  // no container, not doing anything;
1891  // index beyond the end: stays there
1892  if (!cont || (index >= cont->size())) return *this;
1893 
1894  // increment the internal index
1895  ++index;
1896 
1897  // were we in a valid range?
1898  if (currentRange != cont->ranges.end()) {
1899  // if the new index is beyond the current range, pick the next
1900  if (currentRange->end_index() <= index) ++currentRange;
1901  }
1902  // if we have no valid range, we are forever in the void
1903  return *this;
1904 } // lar::sparse_vector<T>::iterator::operator++()
1905 
1906 
1907 template <typename T>
1910  // no container, no idea what to do
1911  if (!cont) throw std::out_of_range("iterator to no sparse vector");
1912 
1913  // index beyond the end: can't return any reference
1914  if (index >= cont->size()) return value_zero;
1915 
1916  // are we in a valid range? if not, we are past the last range
1917  if (currentRange == cont->ranges.end()) return value_zero;
1918 
1919  // if the index is beyond the current range, we are in the void
1920  if (index < currentRange->begin_index()) return value_zero;
1921 
1922  return (*currentRange)[index];
1923 } // lar::sparse_vector<T>::const_iterator::operator*()
1924 
1925 
1926 template <typename T>
1929 {
1930  if (delta == 1) return this->operator++();
1931  index += delta;
1932  if ((currentRange == cont->ranges.end())
1933  || !currentRange->includes(index)
1934  )
1935  refresh_state();
1936  return *this;
1937 } // lar::sparse_vector<T>::const_iterator::operator+=()
1938 
1939 template <typename T>
1942  { return this->operator+= (-delta); }
1943 
1944 
1945 template <typename T>
1948 {
1949  if ((currentRange == cont->ranges.end())
1950  || !currentRange->includes(index + delta)
1951  )
1952  return const_iterator(*cont, index + delta);
1953  const_iterator iter(*this);
1954  iter.index += delta;
1955  return iter;
1956 } // lar::sparse_vector<T>::const_iterator::operator+()
1957 
1958 template <typename T>
1961  { return this->operator+ (-delta); }
1962 
1963 
1965 template <typename T>
1968  (const const_iterator& iter) const
1969 {
1970  if (cont != iter.cont) {
1971  throw std::runtime_error("lar::sparse_vector::const_iterator:"
1972  " difference with alien iterator");
1973  }
1974  return index -iter.index;
1975 } // lar::sparse_vector<T>::const_iterator::operator-(const_iterator)
1976 
1977 
1978 template <typename T>
1980  // update the currentRange
1981  // currentRange is the range including the current item, or next to it
1982  if (cont) {
1983  // the following is actually the range after the index:
1984  currentRange = cont->find_next_range_iter(index);
1985  // if the index is inside the previous index, then we want to move there:
1986  if (currentRange != cont->ranges.begin()) {
1987  if ((currentRange - 1)->end_index() > index) --currentRange;
1988  }
1989  }
1990  else {
1991  currentRange = {};
1992  }
1993 } // lar::sparse_vector<T>::const_iterator::refresh_state()
1994 
1995 
1996 // -----------------------------------------------------------------------------
1997 // --- lar::sparse_vector<T>::iterator implementation
1998 // ---
1999 //
2000 // nothing new so far
2001 //
2002 
2003 
2004 #endif // LARDATAOBJ_UTILITIES_SPARSE_VECTOR_H
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.
Float_t s
Definition: plot.C:23
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.
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)
static size_t expected_vector_size(size_t size)
Returns the expected size taken by a vector of specified size.
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.
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
Definition: sparse_vector.h:44
bool operator<(CryostatID const &a, CryostatID const &b)
Order cryostats with increasing ID.
Definition: geo_types.h:413
reference(const const_reference &from)
intermediate_table::iterator iterator
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.
constexpr bool operator>(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:158
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<=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:165
std::iterator< std::random_access_iterator_tag, T > base_t
base type
Definition: sparse_vector.h:74
const_iterator & operator+=(difference_type delta)
Increment and decrement operators.
value_type value
value to be returned when dereferencing
size_type minimum_size() const
Returns the size determined by the ranges already present.
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.
STL namespace.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
void void_range(range_iterator iRange)
Turns the specified range into void.
reference(value_type *pValue=0)
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, or end() if none.
constexpr bool is_valid(IDNumber_t< L > const id)
Definition: IDNumber.h:112
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.
const_reference(const value_type &value)
container_t::difference_type difference_type
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.
const_iterator get_iterator(size_type index) const
Returns an iterator to the specified absolute value (no check!)
constexpr bool operator>=(Index_t left, Flag_t< Storage > right)
Definition: BitMask.h:172
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.
ranges_const_iterator currentRange
pointer to the current (or next) range
bool is_valid() const
Returns if the vector is in a valid state.
size_type end_index() const
Returns the first absolute index not included in the range.
QuadExpr operator-(double v, const QuadExpr &e)
Definition: QuadExpr.h:38
void move_head(difference_type shift)
Moves the begin of the range by the specified amount.
sparse_vector(sparse_vector &&from)
Move constructor.
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
begin and end 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.
Definition: sparse_vector.h:52
const_iterator cend() const
begin and end iterators
range_list_t ranges
list of ranges
Int_t max
Definition: plot.C:27
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.
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, or end() if none.
intermediate_table::const_iterator const_iterator
sparse_vector & operator=(sparse_vector &&from)
Move assignment.
Namespace for special initialization.
datarange_t()
Default constructor: an empty range.
iterator end()
Standard iterators interface.
datarange_t & extend(size_type index, ITER first, ITER last)
value_const_iterator(value_type new_value, difference_type offset)
Constructor: value to be returned and current iterator "position".
Definition: sparse_vector.h:89
vector_t::size_type size_type
size type
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.
Definition: sparse_vector.h:99
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
value_const_iterator()
Default constructor: use the default value.
Definition: sparse_vector.h:83
std::vector< datarange_t > range_list_t
type of sparse vector data
Little class storing a value.
Definition: sparse_vector.h:43
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
datarange_t & merge_ranges(range_iterator iRange)
Merges all the following ranges.
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.
Definition: DumpUtils.h:424
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)
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.
iterator operator++(int _)
Increment and decrement operators.
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)
Resizes the range (optionally filling the new elements with def_value)
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
Definition: sparse_vector.h:75
iterator()
Default constructor, does not iterate anywhere.
bool operator!=(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to different IDs.
size_type size() const
Returns the size of the range.
void make_void_around(size_type index)
Casts the whole range with the specified item into the void.
A sparse vector.
std::string value(boost::any const &)
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.
range_const_iterator find_range_iterator(size_type index) const
Returns an iterator to the range containing the specified index.
void void_range(size_t iRange)
Turns the specified range into void.
SIZE size_type
type for the indices in the range
LArSoft-specific namespace.
size_type nominal_size
current size
const datarange_t & find_range(size_type index) const
Returns the range containing the specified index.
Int_t min
Definition: plot.C:26
QuadExpr operator+(double v, const QuadExpr &e)
Definition: QuadExpr.h:37
this_t & operator=(value_type)
Assignment: the assigned value is ignored.
Definition: sparse_vector.h:55
vector_t::const_iterator const_iterator
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.
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!!
const_value_box()
Default constructor: stores default value.
Definition: sparse_vector.h:49
reference operator*() const
Dereferenciation operator (can&#39;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
Definition: sparse_vector.h:64
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.
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
begin and end iterators
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
value_const_iterator(value_type new_value)
Constructor: value that will be returned.
Definition: sparse_vector.h:86
iterator(const container_t &c, const typename special::end _)
Special constructor: initializes at the end of the container.
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
size_type last
offset (absolute index) after the last element
const_iterator::container_t container_t
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
const_iterator operator+(difference_type delta) const
Increment and decrement operators.
void assign(ITER first, ITER last)
Copies data from a sequence between two iterators.
A constant iterator returning always the same value.
Definition: sparse_vector.h:71
bool operator==(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to the same ID.
T value_type
type of the value stored
Definition: sparse_vector.h:46
vec_iX clear()
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.
size_type count() const
Returns the number of non-void cells.