9# pragma GCC diagnostic ignored "-Wstringop-overread"
38 if (start < other.fields ()) {
39 field_vector::const_iterator it = other.m_fields.begin ();
46 if (text.empty())
return;
47 std::istringstream in(text);
59 if (text.empty())
return;
60 std::istringstream in(text);
68 for (
size_type i = 0; i < root.fields (); ++i){
99 for (
size_t i = 0; i < subrange.
fields (); ++i) {
100 const field& f = subrange[i];
109 size_t sz = subrange.m_fields.size();
111 for (
size_t i = 0; i <
sz; ++i) {
112 m_fields.emplace_back (std::move(subrange.m_fields[i]));
129 const size_type id_fields =
id.fields ();
136 size_type nfields = (my_fields > id_fields) ? id_fields : my_fields;
138 for (
size_type field_number = 0; field_number < nfields; field_number++) {
140 if (!f.match (
id[field_number]))
return (0);
153 for (
size_type field_number = 0; field_number < my_fields; field_number++) {
156 result << f.get_minimum ();
166 for (
size_type field_number = 0; field_number < my_fields; field_number++) {
169 result << f.get_maximum ();
176 const Range& me = *
this;
178 const field& f = me[i];
179 result *= f.get_indices ();
191 const Range& me = *
this;
196 std::vector<size_type> indices(
id.
fields (), 0);
197 bool is_match =
true;
199 for (; level <
id.fields (); ++level) {
200 const field& f = me[level];
202 if (f.empty())
return 0;
203 if (f.isEnumerated()) {
206 if (f.get_values()[
max] <
id[level]) {
209 indices[level] =
max + 1;
211 for (
size_type j = 0; j < f.get_values().size(); ++j) {
212 if (
id[level] <= f.get_values()[j]) {
213 if (
id[level] != f.get_values()[j]) {
223 if (f.get_maximum() <
id[level]) {
226 indices[level] = f.get_maximum() - f.get_minimum() + 1;
227 }
else if (
id[level] < f.get_minimum()) {
232 indices[level] =
id[level] - f.get_minimum();
235 if (!is_match)
break;
239 if (level <
id.
fields ()) ++level;
242 for (
size_type k = j + 1; k <
id.fields(); ++k) {
243 const field& f = me[k];
244 card *= f.get_indices();
259 const Range& me = *
this;
260 if ((
fields () == 0) || (other.fields () == 0))
return (
false);
262 const field& f1 = me[i];
263 const field& f2 = other[i];
264 if (!f1.overlaps_with (f2))
return (
false);
275 const Range& me = *
this;
276 s << (std::string) me <<
" (";
279 const field& f = me[i];
294 s <<
"=" << allbits <<
") ";
298Range::operator std::string ()
const {
301 if (my_fields == 0)
return (
result);
303 for (
size_type field_number = 0; field_number < my_fields; field_number++) {
305 if (field_number > 0)
result +=
"/";
306 result += (std::string) f;
314 if (
m_fields.size() != other.m_fields.size())
return false;
315 field_vector::const_iterator it1 =
m_fields.begin();
316 field_vector::const_iterator it2 = other.m_fields.begin();
317 field_vector::const_iterator last =
m_fields.end();
318 for (; it1 != last; ++it1, ++it2) {
319 if ((*it1) != (*it2))
return false;
338 for (
int c{}; c!=EOF;c=in.peek()){
342 if (
int c = in.peek();(c ==
'/') or (c ==
' ')){
std::ostream & operator<<(std::ostream &out, const Range &r)
std::istream & operator>>(std::istream &in, Range &r)
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
ExpandedIdentifier maximum() const
int match(const ExpandedIdentifier &id) const
Match an identifier.
ExpandedIdentifier minimum() const
min and max ExpandedIdentifiers (if they exist, ie.
bool operator==(const Range &other) const
void add(element_type value)
Add a required value. (ie. low = high = value)
ExpandedIdentifier::element_type element_type
size_type cardinalityUpTo(const ExpandedIdentifier &id) const
Get the cardinality from the beginning up to the given ExpandedIdentifier.
ExpandedIdentifier::size_type size_type
void build(const std::string &text)
Build Range from a textual description.
const field & operator[](size_type index) const
Access the field elements.
bool overlaps_with(const Range &other) const
Check if two Ranges overlap.
size_type cardinality() const
Computes a possible cardinality :
void clear()
Modifications.