IndexRange.h
Go to the documentation of this file.
1 // IndexRange.h
2 //
3 // David Adams
4 // July 2018
5 //
6 // Data structure that holds a named and labeled contiguous
7 // range of indices. The intention is that the name is unique
8 // (in some context) and can be used as an identifier and to
9 // construct other (e.g. histogram) names. The label is expected
10 // to be used to construct titles and labels for histograms,
11 // plots, etc.
12 //
13 // An arbitrarry number of labesl (op to four in the ctor) may
14 // be assigned to each range.
15 
16 #ifndef IndexRange_H
17 #define IndexRange_H
18 
19 #include <string>
20 #include <vector>
21 #include <iostream>
22 
23 class IndexRange {
24 
25 public:
26 
27  using Index = unsigned int;
28  using Name = std::string;
29  using NameVector = std::vector<Name>;
30 
31  // Data.
32  Name name; // Name
33  NameVector labels; // Label
34  Index begin =0; // First index
35  Index end =0; // Last + 1 index
36 
37  // Ctors.
38  IndexRange() { };
39  IndexRange(Index len) : end(len) { }
40  IndexRange(Index a_begin, Index a_end) : begin(a_begin), end(a_end) { }
41  IndexRange(Name a_name, Index a_begin, Index a_end,
42  Name lab0="", Name lab1="", Name lab2="", Name lab3="")
43  : name(a_name), begin(a_begin), end(a_end) {
44  if ( lab0.size() ) setLabel(0, lab0);
45  if ( lab1.size() ) setLabel(1, lab1);
46  if ( lab2.size() ) setLabel(2, lab2);
47  if ( lab3.size() ) setLabel(3, lab3);
48  }
49  // Ctor from string: name:ich1:ich2, name:ich1:ich2:lab1, ...
50  explicit IndexRange(Name sran) {
51  // name
52  std::string srem = sran;
53  std::string::size_type ipos = srem.find(":");
54  if ( ipos ==0 || ipos == std::string::npos ) return;
55  std::string nameTmp = srem.substr(0, ipos);
56  // begin
57  srem = srem.substr(ipos+1);
58  if ( srem.size() == 0 ) return;
59  ipos = srem.find(":");
60  if ( ipos ==0 || ipos == std::string::npos ) return;
61  std::string swrd = srem.substr(0, ipos);
62  if ( swrd.find_first_not_of("0123456789") != std::string::npos ) return;
63  Index beginTmp = std::stoi(swrd);
64  // end
65  srem = srem.substr(ipos+1);
66  if ( srem.size() == 0 ) return;
67  ipos = srem.find(":");
68  if ( ipos ==0 ) return;
69  swrd = srem.substr(0, ipos);
70  if ( swrd.find_first_not_of( "0123456789" ) != std::string::npos ) return;
71  Index endTmp = std::stoi(swrd);
72  if ( endTmp <= beginTmp ) return;
73  // We now have a valid range.
74  name = nameTmp;
75  begin = beginTmp;
76  end = endTmp;
77  // Add any labels.
78  Index ilab = 0;
79  while ( ipos != std::string::npos ) {
80  srem = srem.substr(ipos+1);
81  swrd = srem.substr(0, ipos);
82  ipos = srem.find(":");
83  setLabel(ilab++, swrd);
84  }
85  }
86 
87  // Length of the range.
88  Index size() const { return end>begin ? end - begin : 0; }
89 
90  // Ordering operator.
91  bool operator<(const IndexRange& rhs) const { return name < rhs.name; }
92 
93  // Other helpers.
94  bool isValid() const { return end > begin; }
95  Index first() const { return begin; }
96  Index last() const { return end > 0 ? end - 1 : 0; }
98  if ( ! isValid() ) return "[]";
99  return "[" + std::to_string(begin) + ", " + std::to_string(end) + ")";
100  }
101  void setLabel(Name lab) { setLabel(0, lab); }
102  void setLabel(Index ilab, Name lab) {
103  labels.resize(ilab+1, "");
104  labels[ilab] = lab;
105  }
106  Name label(Index ilab =0) const {
107  if ( ilab >= labels.size() ) return "";
108  return labels[ilab];
109  }
110  bool contains(Index ival) const { return ival >= begin && ival < end; }
111 
112 };
113 
114 std::ostream& operator<<(std::ostream& lhs, const IndexRange& ir) {
115  lhs << ir.name << ": ";
116  if ( ir.size() == 0 ) {
117  lhs << "<empty>";
118  } else if ( ir.size() == 1 ) {
119  lhs << ir.begin;
120  } else {
121  lhs << "[" << ir.begin << ", " << ir.end << ")";
122  }
123  bool first = true;
124  for ( std::string lab : ir.labels ) {
125  if ( first ) first = false;
126  else lhs << ",";
127  lhs << " " << lab;
128  }
129  return lhs;
130 }
131 
132 #endif
IndexRange(Name sran)
Definition: IndexRange.h:50
NameVector labels
Definition: IndexRange.h:33
IndexRange(Index len)
Definition: IndexRange.h:39
std::string string
Definition: nybbler.cc:12
Index begin
Definition: IndexRange.h:34
std::string Name
Definition: IndexRange.h:28
Index size() const
Definition: IndexRange.h:88
bool isValid() const
Definition: IndexRange.h:94
bool operator<(const IndexRange &rhs) const
Definition: IndexRange.h:91
Index end
Definition: IndexRange.h:35
Name name
Definition: IndexRange.h:32
std::vector< Name > NameVector
Definition: IndexRange.h:29
Index last() const
Definition: IndexRange.h:96
IndexRange(Name a_name, Index a_begin, Index a_end, Name lab0="", Name lab1="", Name lab2="", Name lab3="")
Definition: IndexRange.h:41
std::ostream & operator<<(std::ostream &lhs, const IndexRange &ir)
Definition: IndexRange.h:114
bool contains(Index ival) const
Definition: IndexRange.h:110
IndexRange(Index a_begin, Index a_end)
Definition: IndexRange.h:40
Name label(Index ilab=0) const
Definition: IndexRange.h:106
unsigned int Index
Definition: IndexRange.h:27
Index first() const
Definition: IndexRange.h:95
void setLabel(Index ilab, Name lab)
Definition: IndexRange.h:102
std::string rangeString() const
Definition: IndexRange.h:97
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
void setLabel(Name lab)
Definition: IndexRange.h:101