IndexRangeGroup.h
Go to the documentation of this file.
1 // IndexRangeGroup.h
2 //
3 // David Adams
4 // April 2019
5 //
6 // Data structure that holds a named group of index ranges.
7 // The intention is that the name is unique (in some context)
8 // and can be used as an identifier and to construct other
9 // (e.g. histogram) names. The label is expected to be used
10 // to construct titles and labels for histograms, plots, etc.
11 //
12 // An arbitrarry number of labesl (op to four in the ctor) may
13 // be assigned to each range.
14 
15 #ifndef IndexRangeGroup_H
16 #define IndexRangeGroup_H
17 
19 
21 
22 public:
23 
24  using Index = unsigned int;
25  using IndexVector = std::vector<Index>;
26  using Name = std::string;
27  using NameVector = std::vector<Name>;
28  using RangeVector = std::vector<IndexRange>;
29 
30  // Data.
31  Name name; // Name
32  NameVector labels; // Label
34 
35  // Ctor for empty (invalid) group.
37 
38  // Ctor from name, labels and ranges.
39  IndexRangeGroup(Name a_name, const NameVector& a_labels, const RangeVector& a_ranges)
40  : name(a_name), labels(a_labels), ranges(a_ranges) { }
41 
42  // Ctor from name and ranges (no labels).
43  IndexRangeGroup(Name a_name, const RangeVector& a_ranges)
44  : name(a_name), ranges(a_ranges) { }
45 
46  // Ctor from a single range.
47  explicit IndexRangeGroup(const IndexRange& ran)
48  : name(ran.name), labels(ran.labels), ranges(1, ran) { }
49 
50  // Ctor from a string: sran0 or name,sran0, name,sran0,sran1, ...
51  // where sranN is the string used to construct range N.
52  explicit IndexRangeGroup(std::string sgrp) {
53  std::string srem = sgrp;
54  std::string::size_type ipos = srem.find(",");
55  if ( ipos == std::string::npos ) {
56  IndexRange ran(srem);
57  *this = IndexRangeGroup(ran);
58  return;
59  }
60  std::string nameTmp = srem.substr(0, ipos);
61  while ( ipos != std::string::npos ) {
62  srem = srem.substr(ipos+1);
63  ipos = srem.find(",");
64  std::string sran = srem.substr(0, ipos);
65  IndexRange ran(sran);
66  if ( ! ran.isValid() ) return;
67  ranges.push_back(ran);
68  }
69  }
70 
71  // Length of the range.
72  Index size() const { return ranges.size(); }
73 
74  // Ordering operator.
75  bool operator<(const IndexRangeGroup& rhs) const { return name < rhs.name; }
76 
77  // Other helpers.
78  bool isValid() const { return name.size() || ranges.size(); }
79  IndexRange range(Index iran) const {
80  if ( iran >= size() ) return IndexRange();
81  return ranges[iran];
82  }
83  IndexRange range(Name name) const {
84  for ( const IndexRange& ran : ranges ) {
85  if ( ran.name == name ) return ran;
86  }
87  return IndexRange();
88  }
89  Name label(Index ilab =0) const {
90  if ( ilab >= labels.size() ) return "";
91  return labels[ilab];
92  }
93 
94  void getIndices(IndexVector& idxs) const {
95  for ( const IndexRange& ran : ranges ) {
96  for ( Index ival=ran.begin; ival<ran.end; ++ival ) idxs.push_back(ival);
97  }
98  }
99 };
100 
101 std::ostream& operator<<(std::ostream& lhs, const IndexRangeGroup& ir) {
102  if ( ir.size() == 0 ) {
103  lhs << ir.name << ": <empty>";
104  // If the group holds one range and the range and group names are the same,
105  // then print the range.
106  } else if ( ir.size() == 1 && ir.range(0).name == ir.name ) {
107  lhs << ir.range(0);
108  } else {
109  lhs << ir.name << ": [";
110  bool first = true;
111  for ( const IndexRange& ran : ir.ranges ) {
112  if ( first ) first = false;
113  else lhs << ", ";
114  lhs << ran.name;
115  }
116  lhs << "]";
117  first = true;
118  for ( std::string lab : ir.labels ) {
119  if ( first ) first = false;
120  else lhs << ",";
121  lhs << " " << lab;
122  }
123  }
124  return lhs;
125 }
126 
127 #endif
IndexRange range(Name name) const
std::string string
Definition: nybbler.cc:12
std::vector< IndexRange > RangeVector
Name label(Index ilab=0) const
IndexRangeGroup(Name a_name, const NameVector &a_labels, const RangeVector &a_ranges)
IndexRangeGroup(std::string sgrp)
bool isValid() const
Definition: IndexRange.h:94
IndexRange range(Index iran) const
Name name
Definition: IndexRange.h:32
std::vector< Name > NameVector
std::vector< Index > IndexVector
bool operator<(const IndexRangeGroup &rhs) const
IndexRangeGroup(Name a_name, const RangeVector &a_ranges)
std::string Name
unsigned int Index
RangeVector ranges
std::ostream & operator<<(std::ostream &lhs, const IndexRangeGroup &ir)
NameVector labels
IndexRangeGroup(const IndexRange &ran)
Index size() const
bool isValid() const
void getIndices(IndexVector &idxs) const